package models; import java.util.HashSet; import java.util.Set; import models.helpers.ICleanup; /** * A <code>Tag</code> can belong to several questions, allowing to associate * them thematically and determine user expertise based on overlapping tags of * questions they have successfully answered. * * @author sbuenzli */ public class Tag implements Comparable<Tag> { /** The name of this tag (all lowercase and without whitespace). */ private final String name; /** The questions associated with this tag. */ private final HashSet<Question> questions = new HashSet<Question>(); /** A cleaner to call once this tag isn't referenced by any questions. */ private final ICleanup<Tag> cleaner; /** A regex a valid tag name has to match. */ private final String tagRegex = "^[^A-Z\\s]{1,32}$"; /** * Instantiates a new Tag. Tag names must be all lowercase, may not contain * whitespace and must be at most 32 characters long. * * @param name * the name of this tag (must be all lowercase and not contain * whitespace) * @param cleaner * an optional clean-up object that wants to be notified when * this tag is no longer needed */ public Tag(String name, ICleanup<Tag> cleaner) { if (name == null || !name.matches(this.tagRegex)) throw new IllegalArgumentException(); this.name = name; this.cleaner = cleaner; } /** * @return the name of this Tag. */ public String getName() { return this.name; } /** * @return a list of all the questions associated with this tag. */ public Set<Question> getQuestions() { return (Set<Question>) this.questions.clone(); } /** * @param question * the question to associate with this Tag. */ public void addQuestion(Question question) { this.questions.add(question); } /** * @param question * the question to de-associate from this Tag. */ public void removeQuestion(Question question) { this.questions.remove(question); // remove this tag from the database if (this.questions.isEmpty() && this.cleaner != null) { this.cleaner.cleanUp(this); } } /* * (non-Javadoc) * * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Tag other) { return this.name.compareTo(other.name); } @Override public String toString() { return "Tag(" + this.name + ")"; } }