Java tutorial
/* * 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; } }