package org.jblooming.ontology; import org.jblooming.ApplicationRuntimeException; import org.jblooming.oql.OqlQuery; import org.jblooming.persistence.exceptions.FindException; import org.jblooming.persistence.exceptions.StoreException; import org.jblooming.utilities.StringUtilities; import org.jblooming.waf.html.layout.HtmlColors; import org.jblooming.waf.html.layout.Skin; import java.io.Serializable; import java.util.*; public abstract class PerformantNodeSupport extends PerformantNodeBean implements PerformantNode { protected PerformantNodeSupport parent; private Set<PerformantNodeSupport> children = new HashSet<PerformantNodeSupport>(); public PerformantNodeSupport() { super(); } //PersistenceContext public void setParentAndStore(PerformantNodeSupport n) { //I must not be in n ancestors if (n != null && n.getAncestorIds() != null && n.getAncestorIds().trim().length() > 0 && ((n.getAncestorIds().indexOf(SEPARATOR + this.getId() + SEPARATOR) != -1) || (n.getAncestorIds().startsWith(this.getId() + SEPARATOR))) ) throw new ApplicationRuntimeException( "The parent node cannot be in this node's descendant:" + " parent (id " + n.getId() + ") ancestor ids = '" + n.getAncestorIds() + "' include this (id " + this.getId() + ")"); setParentNode(n); if (n != null) n.addChild(this); if (n != null) { String ancestorIds1 = (n.getAncestorIds() != null ? n.getAncestorIds() : "") + n.getId() + SEPARATOR; setAncestorIds(ancestorIds1); } else setAncestorIds(null); if (getChildrenNode() != null) for (Object o : getChildrenNode()) { PerformantNodeSupport child = (PerformantNodeSupport) o; child.setParentAndStore(this); } } public Iterator<PerformantNodeSupport> getChildrenIterator() { Iterator i; if (children != null) i = children.iterator(); else i = Collections.EMPTY_SET.iterator(); return i; } public Iterator<PerformantNodeSupport> getChildrenIterator(Comparator comp) { Iterator i; if (children != null) { List sort = new ArrayList(children); Collections.sort(sort, comp); i = sort.iterator(); } else i = Collections.EMPTY_SET.iterator(); return i; } public Iterator<PerformantNodeSupport> getChildrenIteratorById() { return getChildrenIterator( new Comparator<PerformantNodeSupport>() { public int compare(PerformantNodeSupport a, PerformantNodeSupport b) { return a.getId().toString().compareTo(b.getId().toString()); } }); } public Iterator<PerformantNodeSupport> getChildrenIteratorByName() { return getChildrenIterator( new Comparator<PerformantNodeSupport>() { public int compare(PerformantNodeSupport a, PerformantNodeSupport b) { return (a.getName()+a.getId()).compareTo(b.getName()+b.getId()); } }); } public int[] getAncestorIdsList() { int[] intIds = null; if (ancestorIds != null) { List stringIds = StringUtilities.splitToList(ancestorIds, SEPARATOR); if (stringIds != null && stringIds.size() > 0) { intIds = new int[stringIds.size() - 1]; for (int i = 0; i < stringIds.size() - 1; i++) { intIds[i] = Integer.parseInt((String) stringIds.get(i)); } } } return intIds; } public List<String> getAncestorIdsAsList() { if (ancestorIds != null) { List<String> strings = StringUtilities.splitToList(ancestorIds, SEPARATOR); if ("".equals(strings.get(strings.size()-1).trim())) strings.remove(strings.size()-1); return strings; } else return new ArrayList(); } /** * list does not include this node id * @param subClazz */ public List<? extends PerformantNodeSupport> getDescendants(Class subClazz) throws FindException { String hql = "from " + subClazz.getName() + " as pns where pns.ancestorIds like :myids_stemmed"; return getPerformantly(hql); } protected List getPerformantly(String hql) throws FindException { OqlQuery oql = new OqlQuery(hql); String param = (ancestorIds != null ? ancestorIds : "") + id + SEPARATOR + "%"; oql.getQuery().setString("myids_stemmed", param); List list = oql.list(); return list; } /** * list does not include this node id * @param subClazz */ public List<Serializable> getDescendantIds(Class subClazz) throws FindException { String hql = "select pns.id from " + subClazz.getName() + " as pns where pns.ancestorIds like :myids_stemmed"; return getPerformantly(hql); } public int getDescendantsSize(Class subClazz) throws FindException { String hql = "select count(pns.id) from " + subClazz.getName() + " as pns where pns.ancestorIds like :myids_stemmed"; return ((Long) getPerformantly(hql).iterator().next()).intValue(); } public int getMaxDepthOfDescendants(Class subClazz) throws FindException { int result = 0; for (Serializable id : getDescendantIds(subClazz)) { result = Math.max(result, StringUtilities.occurrences(id.toString(), SEPARATOR)); } return result; } /** * * @return a list of encestors including this */ public List getAncestors() { if (this.getParentNode() == null) { List recursor = new ArrayList(); recursor.add(this); return recursor; } else { List recursor = ((PerformantNodeSupport) this.getParentNode()).getAncestors(); recursor.add(this); return recursor; } } public static void recalculatePerformantNodesAndStore(PerformantNodeSupport rootNode) throws StoreException { if (rootNode != null) { List<Node> ancs = rootNode.getAncestors(); for (int i = 0; i < ancs.size(); i++) { PerformantNodeSupport node = (PerformantNodeSupport) ancs.get(i); if (node.getParentNode() != null) node.setParentAndStore((PerformantNodeSupport) node.getParentNode()); node.store(); } } } public static void recalculatePerformantNodesAndStore(Set<? extends PerformantNodeSupport> nodes) throws StoreException { for (PerformantNodeSupport performantNode : nodes) { List<Node> ancs = performantNode.getAncestors(); for (int i = 0; i < ancs.size(); i++) { PerformantNodeSupport node = (PerformantNodeSupport) ancs.get(i); if (node.getParentNode() != null) node.setParentAndStore((PerformantNodeSupport) node.getParentNode()); node.store(); } } } public PerformantNodeSupport getAncestor() { if (this.getParentNode() == null) { return this; } else { return ((PerformantNodeSupport) this.getParentNode()).getAncestor(); } } public int getDepth() { int[] ancestorIdsList = getAncestorIdsList(); if (ancestorIdsList != null) return ancestorIdsList.length; else return 0; } public Set<PerformantNodeSupport> getChildren() { return children; } private void setChildren(Set<PerformantNodeSupport> children) { this.children = children; } public Collection getChildrenNode() { return getChildren(); } public void addChild(PerformantNodeSupport pns) { getChildren().add(pns); } public int getChildrenSize() { return getChildren() != null ? getChildren().size() : 0; } public boolean childrenContains(Node child) { return getChildren().contains(child); } public int childrenSize() { return getChildren().size(); } public abstract Node getParentNode(); public abstract void setParentNode(Node node); public PerformantNodeSupport getPreviousBrother() { PerformantNodeSupport brother = null; PerformantNodeSupport parent = (PerformantNodeSupport) getParentNode(); if (parent != null && parent.getChildrenSize() > 1) { Iterator i = parent.getChildrenIteratorByName(); while (i.hasNext()) { PerformantNodeSupport node = (PerformantNodeSupport) i.next(); if (node.equals(this)) break; brother = node; } } return brother; } public PerformantNodeSupport getNextBrother() { PerformantNodeSupport brother = null; PerformantNodeSupport parent = (PerformantNodeSupport) getParentNode(); boolean foundMyself = false; if (parent != null && parent.getChildrenSize() > 1) { Iterator i = parent.getChildrenIteratorByName(); while (i.hasNext()) { PerformantNodeSupport task = (PerformantNodeSupport) i.next(); if (foundMyself) { brother = task; break; } if (task.equals(this)) foundMyself = true; } } return brother; } public List<PerformantNodeSupport> getBrothers() { List<PerformantNodeSupport> brothers = new ArrayList<PerformantNodeSupport>(); PerformantNodeSupport parent = (PerformantNodeSupport) getParentNode(); if (parent != null && parent.getChildrenSize() > 1) { Iterator i = parent.getChildrenIteratorByName(); while (i.hasNext()) { PerformantNodeSupport child = (PerformantNodeSupport) i.next(); if (!child.equals(this)) { brothers.add(child); } } } return brothers; } public String getPath(String separator) { List<PerformantNodeSupport> ancs = getAncestors(); String path = ""; boolean first = true; for (PerformantNodeSupport anc : ancs) { path = path + (first ? "" : separator) + anc.getName(); first = false; } return path; } public String getDepthColor(Skin skin) { return HtmlColors.getDepthColor(this.getDepth(), skin); } public String getChildAncentorIds(){ return this.getAncestorIds() == null ? getId() + PerformantNode.SEPARATOR : this.getAncestorIds() + getId() + PerformantNode.SEPARATOR; } }