/* This file is part of JFLICKS. JFLICKS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JFLICKS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JFLICKS. If not, see <http://www.gnu.org/licenses/>. */ package org.jflicks.photomanager; import java.io.Serializable; import java.util.ArrayList; import org.jflicks.util.LogUtil; /** * This class contains all the properties representing a tag. * * @author Doug Barnum * @version 1.0 */ public class Tag implements Serializable, Comparable<Tag> { private int id; private int parentId; private String name; private Tag parent; private ArrayList<Tag> childrenList; private int level = -1; private String path = null; /** * Simple empty constructor. */ public Tag() { setChildrenList(new ArrayList<Tag>()); } /** * Constructor to "clone" a Tag instance. * * @param t A given Tag. */ public Tag(Tag t) { this(); setId(t.getId()); setParentId(t.getParentId()); setName(t.getName()); setParent(t.getParent()); setChildren(t.getChildren()); } /** * An Id is associated with this object. * * @return An Id value as an int. */ public int getId() { return (id); } /** * An Id is associated with this object. * * @param i An Id value as an int. */ public void setId(int i) { id = i; } /** * A ParentId is associated with this object so it's possible to find * a parent even if the Parent property is null. * * @return A ParentId value as an int. */ public int getParentId() { return (parentId); } /** * A ParentId is associated with this object so it's possible to find * a parent even if the Parent property is null. * * @param i A ParentId value as an int. */ public void setParentId(int i) { parentId = i; } /** * A Name is associated with this object. * * @return A Name value as a String. */ public String getName() { return (name); } /** * A Name is associated with this object. * * @param s A Name value as a String. */ public void setName(String s) { name = s; } /** * The parent of this tag. * * @return The parent Tag if it exists. */ public Tag getParent() { return (parent); } /** * The parent of this tag. * * @param t The parent Tag if it exists. */ public void setParent(Tag t) { parent = t; } /** * All of our kids. * * @return An array of Tag instances. */ public Tag[] getChildren() { Tag[] result = null; ArrayList<Tag> l = getChildrenList(); if ((l != null) && (l.size() > 0)) { result = l.toArray(new Tag[l.size()]); } return (result); } /** * All of our kids. * * @param array An array of Tag instances. */ public void setChildren(Tag[] array) { ArrayList<Tag> l = getChildrenList(); if (l != null) { l.clear(); if (array != null) { for (int i = 0; i < array.length; i++) { l.add(array[i]); } } } } /** * Add a child. * * @param t A tag to add. */ public void addChild(Tag t) { ArrayList<Tag> l = getChildrenList(); if ((t != null) && (l != null)) { l.add(t); t.setParent(this); } } /** * Remove a child. * * @param t A tag to remove. */ public void removeChild(Tag t) { ArrayList<Tag> l = getChildrenList(); if ((t != null) && (l != null)) { l.remove(t); } } private ArrayList<Tag> getChildrenList() { return (childrenList); } private void setChildrenList(ArrayList<Tag> l) { childrenList = l; } /** * Convenience method to determine if this Tag is the one and only root. * * @return True if we are root. */ public boolean isRoot() { return (getParent() == null); } /** * Convenience method to determine if we are childless. * * @return True if we are a leaf. */ public boolean isLeaf() { return (getChildren() == null); } /** * The level deep into the Tag tree we reside. Root would be zero. * * @return An int value. */ public int getLevel() { if (level == -1) { level = 0; Tag p = getParent(); while (p != null) { level++; p = p.getParent(); } } return (level); } /** * Return the number of decendants. * * @return The count as an int value. */ public int count() { int result = 1; if (!isLeaf()) { Tag[] kids = getChildren(); for (int i = 0; i < kids.length; i++) { result += kids[i].count(); } } return (result); } /** * Turn this Tag and it's parents into a String separated by "/" * characters. * * @return A String instance. */ public String toPath() { if (path == null) { if (isRoot()) { path = ""; } else { Tag p = getParent(); path = p.toPath() + "/" + getName(); } } return (path); } /** * Convenience method to get a child with the given name. * * @param s A given name as a String. * @return A Tag if it exists. */ public Tag getChildByName(String s) { Tag result = null; Tag[] kids = getChildren(); if ((kids != null) && (s != null)) { for (int i = 0; i < kids.length; i++) { if (s.equals(kids[i].getName())) { result = kids[i]; break; } } } return (result); } /** * Convenience method to see if a child exists with the given name. * * @param s A given name as a String. * @return True if it exists. */ public boolean hasChildByName(String s) { boolean result = false; Tag[] kids = getChildren(); if ((kids != null) && (s != null)) { for (int i = 0; i < kids.length; i++) { if (s.equals(kids[i].getName())) { result = true; break; } } } return (result); } /** * Flatten out out Tag to an array of Tag instances. * * @return An arrat of Tag objects. */ public Tag[] toArray() { Tag[] result = null; ArrayList<Tag> l = new ArrayList<Tag>(); toArray(this, l); if (l.size() > 0) { result = l.toArray(new Tag[l.size()]); } return (result); } private void toArray(Tag t, ArrayList<Tag> l) { if (t != null) { l.add(t); Tag[] kids = t.getChildren(); if (kids != null) { for (int i = 0; i < kids.length; i++) { toArray(kids[i], l); } } } } /** * The standard hashcode override. * * @return An int value. */ public int hashCode() { return (toPath().hashCode()); } /** * We override equals. * * @param o A given object to compare. * @return True when equal. */ public boolean equals(Object o) { boolean result = false; if (o == this) { result = true; } else if (!(o instanceof Tag)) { result = false; } else { Tag t = (Tag) o; String s = toPath(); if (s != null) { result = s.equals(t.toPath()); } } return (result); } /** * The comparable interface. * * @param t The given Tag instance to compare. * @throws ClassCastException on the input argument. * @return An int representing their "equality". */ public int compareTo(Tag t) throws ClassCastException { int result = 0; if (t == null) { throw new NullPointerException(); } if (t == this) { result = 0; } else { String path0 = toPath(); String path1 = t.toPath(); if ((path0 != null) && (path1 != null)) { result = path0.compareTo(path1); } } return (result); } /** * Debug method to print out our root Tag. */ public void dump() { LogUtil.log(LogUtil.INFO, "id: " + getId() + " name <" + getName() + "> path <" + toPath() + ">"); Tag[] kids = getChildren(); if (kids != null) { for (int i = 0; i < kids.length; i++) { kids[i].dump(); } } } }