2 * Sonitus - ContentMetadata.java - Copyright © 2013 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sonitus.data;
20 import java.util.Arrays;
22 import com.google.common.base.Joiner;
23 import com.google.common.base.Optional;
24 import com.google.common.base.Preconditions;
27 * The part of the {@link Metadata} that contains information about the content
28 * of a {@link Source}, such as the name of the track, the artist, or other
31 * Content metadata also contains a “title” which is an amalgamation of all
32 * information in the content metadata. If not given, it will be automatically
33 * constructed from all other information. If can also be specified manually to
34 * override the default.
36 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
38 public class ContentMetadata {
41 private final Optional<String> artist;
44 private final Optional<String> name;
46 /** The all-in-one title. */
47 private final String title;
50 private final Optional<String> comment;
52 /** Creates empty content metadata. */
53 public ContentMetadata() {
58 * Creates content metadata containing the given title.
61 * The title of the metadata
62 * @throws NullPointerException
63 * if {@code title} is {@code null}
65 public ContentMetadata(String title) throws NullPointerException {
66 this(null, null, title, null);
70 * Creates content metadata.
73 * The artist of the track
75 * The name of the track
77 public ContentMetadata(String artist, String name) {
78 this(artist, name, joinStrings(artist, name), null);
82 * Creates content metadata.
85 * The artist of the track (may be null)
87 * The name of the track (may be null)
89 * The title of the track
91 * The comment of the track
92 * @throws NullPointerException
93 * if {@code title} is {@code null}
95 private ContentMetadata(String artist, String name, String title, String comment) throws NullPointerException {
96 this.artist = Optional.fromNullable(artist);
97 this.name = Optional.fromNullable(name);
98 this.title = Preconditions.checkNotNull(title, "title must not be null");
99 this.comment = Optional.fromNullable(comment);
107 * Returns the artist of the track, if it has been set.
109 * @return The artist of the track
111 public Optional<String> artist() {
116 * Returns the name of the track, if it has been set.
118 * @return The name of the track
120 public Optional<String> name() {
125 * Returns the title of the track.
127 * @return The title of the track
129 public String title() {
134 * Returns the comment of the track, if it has been set.
136 * @return The comment of the track
138 public Optional<String> comment() {
147 * Creates new content metadata that is a copy of this content metadata but
148 * with the artist changed. The title will be reconstructed from the new artist
149 * and the existing name.
153 * @return The new content metadata
155 public ContentMetadata artist(String artist) {
156 return new ContentMetadata(artist, name().orNull(), joinStrings(artist, name().orNull()), comment.orNull());
160 * Creates new content metadata that is a copy of this content metadata but
161 * with the name changed. The title will be reconstructed from the existing
162 * artist and the new name.
166 * @return The new content metadata
168 public ContentMetadata name(String name) {
169 return new ContentMetadata(artist().orNull(), name, joinStrings(artist().orNull(), name), comment.orNull());
173 * Creates new content metadata that is a copy of this content metadata but
174 * with the title changed.
178 * @return The new content metadata
180 public ContentMetadata title(String title) {
181 return new ContentMetadata(artist().orNull(), name().orNull(), title, comment.orNull());
185 * Creates new content metadata that is a copy of this content metadata but
186 * with the comment changed.
190 * @return The new content metadata
192 public ContentMetadata comment(String comment) {
193 return new ContentMetadata(artist().orNull(), name().orNull(), title(), comment);
197 * Returns whether this content metadata object equals the given object if the
198 * comments of this and the given object are ignored.
201 * The object to compare to this one
202 * @return {@code true} if the given object and this object are equal if the
203 * comments are ignored, {@code false} otherwise
205 public boolean equalsIgnoreComment(Object object) {
206 if (!(object instanceof ContentMetadata)) {
209 ContentMetadata contentMetadata = (ContentMetadata) object;
210 return artist().equals(contentMetadata.artist()) && name().equals(contentMetadata.name()) && title().equals(contentMetadata.title());
218 public int hashCode() {
219 return artist().hashCode() ^ name().hashCode() ^ title().hashCode() ^ comment().hashCode();
223 public boolean equals(Object object) {
224 if (!(object instanceof ContentMetadata)) {
227 ContentMetadata contentMetadata = (ContentMetadata) object;
228 return artist().equals(contentMetadata.artist()) && name().equals(contentMetadata.name()) && title().equals(contentMetadata.title()) && comment().equals(contentMetadata.comment());
232 public String toString() {
233 return String.format("%s%s", title(), comment().isPresent() ? String.format(" (%s)", comment().get()) : "");
241 * Joins the given strings, concatenating them with “ - ” and ignoring {@code
245 * The strings to join
246 * @return The joined strings
248 private static String joinStrings(String... strings) {
249 return Joiner.on(" - ").skipNulls().join(Arrays.asList(strings));