/* * Copyright (c) 2006-2009 by Dirk Riehle, http://dirkriehle.com * * This file is part of the Wahlzeit photo rating application. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/>. */ package org.wahlzeit.model; import org.wahlzeit.utils.StringUtil; import java.io.Serializable; import java.util.Set; import java.util.TreeSet; /** * A Tags instance represents a set of tags; each tag ist just a string. * All tags are maintained lowercase and without whitespace. * For example, "Captain America" turns into "captainamerica". */ public class Tags implements Serializable { /** * */ public static final char SEPARATOR_CHAR = ','; /** * */ public static final int MAX_NO_TAGS = 32; /** * */ public static final Tags EMPTY_TAGS = new Tags(); /** * */ private final char separator; /** * */ protected Set<String> tags = new TreeSet<String>(); /** * */ public Tags() { // do nothing this.separator = SEPARATOR_CHAR; } /** * */ public Tags(String myTags) { this.separator = SEPARATOR_CHAR; this.tags = asTagSetFromString(myTags); } /** * */ public Tags(String myTags, char separator) { this.separator = separator; this.tags = asTagSetFromString(myTags, separator); } /** * @methodtype boolean-query */ @Override public int hashCode() { return (tags == null) ? super.hashCode() : tags.hashCode(); } /** * */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Tags)) return false; Tags other = (Tags) obj; return isEqual(other); } /** * */ public boolean isEqual(Tags other) { if (tags == null) { return other.tags == null; } return tags.equals(other.tags); } /** * */ public boolean hasTag(String tag) { return (null != tag) && tags.contains(tag); } /** * @methodtype get */ public int getSize() { return tags.size(); } /** * @methodtype conversion */ public String asString() { return asString(false, separator); } /** * */ public String asString(boolean lead, char sep) { StringBuffer result = new StringBuffer(); String seps = (lead ? " " : "") + sep + " "; String[] myTags = asArray(); for (int i = 0; i < myTags.length; i++) { if (i != 0) result.append(seps); result.append(myTags[i]); } return result.toString(); } /** * */ public String[] asArray() { return tags.toArray(new String[tags.size()]); } /** * @methodtype conversion * @methodproperties convenience, class */ public static Set<String> asTagSetFromString(String tags) { return asTagSetFromString(tags, SEPARATOR_CHAR); } /** * @methodtype conversion * @methodproperties class */ public static Set<String> asTagSetFromString(String tags, char separator) { Set<String> result = new TreeSet<String>(); if (tags != null) { int i = 0; int j = 0; for (; i < tags.length(); i = j) { for (; ((i < tags.length()) && (tags.charAt(i) == separator)); ) { i++; } for (j = i; ((j < tags.length()) && (tags.charAt(j) != separator)); ) { j++; } if (i != j) { String tag = asTag(tags.substring(i, j)); if (!StringUtil.isNullOrEmptyString(tag)) { result.add(tag); } } } } return result; } /** * */ public static String asTag(String n) { StringBuffer result = new StringBuffer(n.length()); for (int i = 0; i < n.length(); i++) { char c = n.charAt(i); if (Character.isLetter(c)) { result.append(Character.toLowerCase(c)); } else if (Character.isDigit(c)) { result.append(c); } } return result.toString(); } }