0903457a4333d3f27175445da40c3abfe5e56b37
[sonitus.git] / Metadata.java
1 /*
2  * Sonitus - Metainfo.java - Copyright © 2013 David Roden
3  *
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.
8  *
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.
13  *
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/>.
16  */
17
18 package net.pterodactylus.sonitus.data;
19
20 import com.google.common.base.Optional;
21
22 /**
23  * Metadata contains information about a source, e.g. the number of channels,
24  * the frequency, the encoding, the name of the content, the artist performing
25  * it, dates, comments, URLs, etc.
26  * <p/>
27  * Metadata, once created, is immutable.
28  *
29  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
30  */
31 public class Metadata {
32
33         /** The format metadata. */
34         private final FormatMetadata formatMetadata;
35
36         /** The content metadata. */
37         private final ContentMetadata contentMetadata;
38
39         /** Creates empty metadata. */
40         public Metadata() {
41                 this(new FormatMetadata(), new ContentMetadata());
42         }
43
44         /**
45          * Creates metadata from the given format and content metadata.
46          *
47          * @param formatMetadata
48          *              The format metadata
49          * @param contentMetadata
50          *              The content metadata
51          */
52         public Metadata(FormatMetadata formatMetadata, ContentMetadata contentMetadata) {
53                 this.formatMetadata = formatMetadata;
54                 this.contentMetadata = contentMetadata;
55         }
56
57         //
58         // ACCESSORS
59         //
60
61         /**
62          * Returns the embedded format metadata.
63          *
64          * @return The format metadata
65          */
66         public FormatMetadata format() {
67                 return formatMetadata;
68         }
69
70         /**
71          * Returns the embedded content metadata.
72          *
73          * @return The content metadata
74          */
75         public ContentMetadata content() {
76                 return contentMetadata;
77         }
78
79         /**
80          * Returns the number of channels of this metadata.
81          *
82          * @return The number of channels of this metadata
83          */
84         public int channels() {
85                 return formatMetadata.channels();
86         }
87
88         /**
89          * Returns a metadata with the same parameters as this metadata and the given
90          * number of channels.
91          *
92          * @param channels
93          *              The new number of channels
94          * @return A new metadata with the given number of channels
95          */
96         public Metadata channels(int channels) {
97                 return new Metadata(formatMetadata.channels(channels), contentMetadata);
98         }
99
100         /**
101          * Returns the sampling frequency of this metadata.
102          *
103          * @return The sampling frequency of this metadata
104          */
105         public int frequency() {
106                 return formatMetadata.frequency();
107         }
108
109         /**
110          * Returns a new metadata with the same parameters as this metadata and the
111          * given frequency.
112          *
113          * @param frequency
114          *              The new frequency
115          * @return A new metadata with the given frequency
116          */
117         public Metadata frequency(int frequency) {
118                 return new Metadata(formatMetadata.frequency(frequency), contentMetadata);
119         }
120
121         /**
122          * Returns the encoding of this metadata
123          *
124          * @return The encoding of this metadata
125          */
126         public String encoding() {
127                 return formatMetadata.encoding();
128         }
129
130         /**
131          * Returns a new metadata with the same parameters as this metadata and the
132          * given encoding.
133          *
134          * @param encoding
135          *              The new encoding
136          * @return A new metadata with the given encoding
137          */
138         public Metadata encoding(String encoding) {
139                 return new Metadata(formatMetadata.encoding(encoding), contentMetadata);
140         }
141
142         /**
143          * Returns the artist, if any.
144          *
145          * @return The artist, or {@link Optional#absent()}
146          */
147         public Optional<String> artist() {
148                 return contentMetadata.artist();
149         }
150
151         /**
152          * Returns new metadata with the same attributes as this metadata, except for
153          * the artist.
154          *
155          * @param artist
156          *              The new artist
157          * @return New metadata with a changed artist
158          */
159         public Metadata artist(String artist) {
160                 return new Metadata(formatMetadata, contentMetadata.artist(artist));
161         }
162
163         /**
164          * Returns the name of the content, if any.
165          *
166          * @return The name, or {@link Optional#absent()}
167          */
168         public Optional<String> name() {
169                 return contentMetadata.name();
170         }
171
172         /**
173          * Returns new metadata with the same attributes as this metadata, except for
174          * the name.
175          *
176          * @param name
177          *              The new name
178          * @return New metadata with a changed name
179          */
180         public Metadata name(String name) {
181                 return new Metadata(formatMetadata, contentMetadata.name(name));
182         }
183
184         /**
185          * Returns the title of the content.
186          *
187          * @return The title of the content
188          */
189         public String title() {
190                 return contentMetadata.title();
191         }
192
193         /**
194          * Returns new metadata with the same attributes as this metadata but with the
195          * title changed to the given title.
196          *
197          * @param title
198          *              The new title
199          * @return The new metadata
200          */
201         public Metadata title(String title) {
202                 return new Metadata(formatMetadata, contentMetadata.title(title));
203         }
204
205         //
206         // OBJECT METHODS
207         //
208
209         @Override
210         public int hashCode() {
211                 return formatMetadata.hashCode() ^ contentMetadata.hashCode();
212         }
213
214         @Override
215         public boolean equals(Object object) {
216                 if (!(object instanceof Metadata)) {
217                         return false;
218                 }
219                 Metadata metadata = (Metadata) object;
220                 return formatMetadata.equals(metadata.formatMetadata) && contentMetadata.equals(metadata.contentMetadata);
221         }
222
223         @Override
224         public String toString() {
225                 return String.format("%s%s%s", formatMetadata, contentMetadata.toString().length() > 0 ? ": " : "", contentMetadata);
226         }
227
228 }