com.hp.alm.ali.idea.entity.tree.EntityNode.java Source code

Java tutorial

Introduction

Here is the source code for com.hp.alm.ali.idea.entity.tree.EntityNode.java

Source

/*
 * Copyright 2013 Hewlett-Packard Development Company, L.P
 *
 * 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.hp.alm.ali.idea.entity.tree;

import com.hp.alm.ali.idea.model.Entity;
import com.hp.alm.ali.idea.model.Metadata;
import com.intellij.openapi.util.Pair;
import org.apache.commons.lang.StringUtils;

import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class EntityNode implements TreeNode, Comparable<EntityNode> {
    private int ordering;
    private HierarchicalEntityModel model;
    private EntityNode parent;

    private Entity entity;
    private List<EntityNode> children;

    private List<EntityNode> filtered;
    private boolean childMatching;
    private boolean incomplete;
    private boolean loading;

    public EntityNode(HierarchicalEntityModel model, EntityNode parent, Entity entity) {
        this.model = model;
        this.parent = parent;
        this.entity = entity;

        model.addNode(this);
    }

    public void initChildren() {
        if (children == null) {
            children = new ArrayList<EntityNode>();
            filtered = new ArrayList<EntityNode>();
            model.lazyLoadChildren(Arrays.asList(this), true);
        }
    }

    public void storeChildren(List<EntityNode> children) {
        if (this.children == null) {
            this.children = new ArrayList<EntityNode>();
            this.filtered = new ArrayList<EntityNode>();
        }
        // TODO: keep sorted

        mergeChildren(children);

        this.children.clear();
        this.children.addAll(children);

        incomplete = false;
        loading = false;
    }

    public void filterVisible() {
        if (children != null) {
            mergeChildren(children);
        }
        model.nodeChanged(this);
    }

    private void mergeChildren(List<EntityNode> children) {
        for (int i = 0; i < this.filtered.size(); i++) {
            EntityNode child = this.filtered.get(i);
            if (!children.contains(child) || (!child.matchesFilter() && !child.isChildMatching())) {
                this.filtered.remove(i);
                model.nodesWereRemoved(this, new int[] { i }, new EntityNode[] { child });
                --i;
            }
        }
        for (EntityNode child : children) {
            if (!filtered.contains(child)) {
                if (child.matchesFilter() || child.isChildMatching()) {
                    int i = Collections.binarySearch(this.filtered, child);
                    this.filtered.add(-(i + 1), child);
                    model.nodesWereInserted(this, new int[] { -(i + 1) });
                }
            }
        }
    }

    public EntityNode getChildAt(int i) {
        initChildren();
        return filtered.get(i);
    }

    public int getChildCount() {
        initChildren();
        return filtered.size();
    }

    public EntityNode getParent() {
        return parent;
    }

    public int getIndex(TreeNode treeNode) {
        initChildren();
        return filtered.indexOf(treeNode);
    }

    public boolean getAllowsChildren() {
        return !isLeaf();
    }

    public boolean isLeaf() {
        List<String> childrenTypes = Metadata.getChildEntity(entity.getType());
        return childrenTypes == null
                || (model.getEntityType().equals(entity.getType()) && !childrenTypes.contains(entity.getType()));
    }

    public Enumeration children() {
        initChildren();
        return Collections.enumeration(getFiltered());
    }

    public Entity getEntity() {
        return entity;
    }

    public String toString() {
        String name = entity.getPropertyValue("name");
        if (loading) {
            name += "..."; // TODO: show as icon
        }
        String filter = model.getFilter();
        if (!filter.isEmpty()) {
            Matcher matcher = Pattern.compile(wildcardToRegex(filter), Pattern.CASE_INSENSITIVE).matcher(name);
            List<Pair<Integer, Integer>> list = new LinkedList<Pair<Integer, Integer>>();
            while (matcher.find()) {
                list.add(new Pair<Integer, Integer>(matcher.start(), matcher.end()));
            }
            if (!list.isEmpty()) {
                Collections.reverse(list);
                for (Pair<Integer, Integer> match : list) {
                    name = name.substring(0, match.first) + "<b>" + name.substring(match.first, match.second)
                            + "</b>" + name.substring(match.second);
                }
                return "<html>" + name + "</html>";
            }
        }
        return name;
    }

    public List<EntityNode> getPath() {
        List<EntityNode> path;
        if (parent == null) {
            path = new ArrayList<EntityNode>();
        } else {
            path = parent.getPath();
        }
        path.add(this);
        return path;
    }

    public boolean addFilteredChild(EntityNode node) {
        if (children == null) {
            children = new ArrayList<EntityNode>();
            incomplete = true;
        }
        children.add(node);

        if (filtered == null) {
            filtered = new ArrayList<EntityNode>();
        }
        filtered.add(node);
        return incomplete;
    }

    public List<EntityNode> getFiltered() {
        return filtered;
    }

    public boolean matchesFilter() {
        if (parent != null && parent.matchesFilter()) {
            return true;
        } else {
            return model.getFilter().isEmpty()
                    || containsIgnoreCase(entity.getPropertyValue("name"), model.getFilter());
        }
    }

    private boolean containsIgnoreCase(String str, String subStr) {
        return Pattern.compile(".*" + wildcardToRegex(subStr) + ".*", Pattern.CASE_INSENSITIVE).matcher(str)
                .matches();
    }

    private String wildcardToRegex(String mask) {
        String[] tokens = mask.split("\\*", -1);
        for (int i = 0; i < tokens.length; i++) {
            tokens[i] = Pattern.quote(tokens[i]);
        }
        return StringUtils.join(tokens, ".*");
    }

    public boolean isChildMatching() {
        return childMatching;
    }

    public void setChildMatching(boolean childMatching) {
        this.childMatching = childMatching;
    }

    public boolean isIncomplete() {
        return incomplete;
    }

    public void setIncomplete(boolean b) {
        this.incomplete = b;
    }

    public int compareTo(EntityNode entityNode) {
        int ret = ordering - entityNode.ordering;
        if (ret == 0) {
            return getEntity().getPropertyValue("name").compareTo(entityNode.getEntity().getPropertyValue("name"));
        } else {
            return ret;
        }
    }

    public boolean isLoading() {
        return loading;
    }

    public void setLoading(boolean loading) {
        this.loading = loading;
    }

    public void setOrdering(int ordering) {
        this.ordering = ordering;
    }
}