Expose format and content metadata.
[sonitus.git] / src / main / java / net / pterodactylus / sonitus / data / Metadata.java
index 22fbb27..9c3f85e 100644 (file)
@@ -20,10 +20,9 @@ package net.pterodactylus.sonitus.data;
 import com.google.common.base.Optional;
 
 /**
- * Metadata contains information about a source, e.g. the name of the content,
- * the artist performing it, dates, comments, URLs, etc. The {@link Format},
- * however, is not part of the metadata because a {@link Source} already exposes
- * it.
+ * Metadata contains information about a source, e.g. the number of channels,
+ * the frequency, the encoding, the name of the content, the artist performing
+ * it, dates, comments, URLs, etc.
  * <p/>
  * Metadata, once created, is immutable.
  *
@@ -31,28 +30,113 @@ import com.google.common.base.Optional;
  */
 public class Metadata {
 
-       /** The artist performing the content. */
-       private final Optional<String> artist;
+       /** The format metadata. */
+       private final FormatMetadata formatMetadata;
 
-       /** The name of the content. */
-       private final Optional<String> name;
+       /** The content metadata. */
+       private final ContentMetadata contentMetadata;
 
        /** Creates empty metadata. */
        public Metadata() {
-               this(null, null);
+               this(new FormatMetadata(), new ContentMetadata());
        }
 
        /**
-        * Creates metadata with the given attributes.
+        * Creates metadata from the given format and content metadata.
         *
-        * @param artist
-        *              The artist performing the content (may be {@code null})
-        * @param name
-        *              The name of the content (may be {@code null})
+        * @param formatMetadata
+        *              The format metadata
+        * @param contentMetadata
+        *              The content metadata
+        */
+       public Metadata(FormatMetadata formatMetadata, ContentMetadata contentMetadata) {
+               this.formatMetadata = formatMetadata;
+               this.contentMetadata = contentMetadata;
+       }
+
+       //
+       // ACCESSORS
+       //
+
+       /**
+        * Returns the embedded format metadata.
+        *
+        * @return The format metadata
+        */
+       public FormatMetadata format() {
+               return formatMetadata;
+       }
+
+       /**
+        * Returns the embedded content metadata.
+        *
+        * @return The content metadata
+        */
+       public ContentMetadata content() {
+               return contentMetadata;
+       }
+
+       /**
+        * Returns the number of channels of this metadata.
+        *
+        * @return The number of channels of this metadata
+        */
+       public int channels() {
+               return formatMetadata.channels();
+       }
+
+       /**
+        * Returns a metadata with the same parameters as this metadata and the given
+        * number of channels.
+        *
+        * @param channels
+        *              The new number of channels
+        * @return A new metadata with the given number of channels
+        */
+       public Metadata channels(int channels) {
+               return new Metadata(formatMetadata.channels(channels), contentMetadata);
+       }
+
+       /**
+        * Returns the sampling frequency of this metadata.
+        *
+        * @return The sampling frequency of this metadata
+        */
+       public int frequency() {
+               return formatMetadata.frequency();
+       }
+
+       /**
+        * Returns a new metadata with the same parameters as this metadata and the
+        * given frequency.
+        *
+        * @param frequency
+        *              The new frequency
+        * @return A new metadata with the given frequency
+        */
+       public Metadata frequency(int frequency) {
+               return new Metadata(formatMetadata.frequency(frequency), contentMetadata);
+       }
+
+       /**
+        * Returns the encoding of this metadata
+        *
+        * @return The encoding of this metadata
         */
-       private Metadata(String artist, String name) {
-               this.artist = Optional.fromNullable(artist);
-               this.name = Optional.fromNullable(name);
+       public String encoding() {
+               return formatMetadata.encoding();
+       }
+
+       /**
+        * Returns a new metadata with the same parameters as this metadata and the
+        * given encoding.
+        *
+        * @param encoding
+        *              The new encoding
+        * @return A new metadata with the given encoding
+        */
+       public Metadata encoding(String encoding) {
+               return new Metadata(formatMetadata.encoding(encoding), contentMetadata);
        }
 
        /**
@@ -61,7 +145,7 @@ public class Metadata {
         * @return The artist, or {@link Optional#absent()}
         */
        public Optional<String> artist() {
-               return artist;
+               return contentMetadata.artist();
        }
 
        /**
@@ -73,7 +157,7 @@ public class Metadata {
         * @return New metadata with a changed artist
         */
        public Metadata artist(String artist) {
-               return new Metadata(artist, this.artist.orNull());
+               return new Metadata(formatMetadata, contentMetadata.artist(artist));
        }
 
        /**
@@ -82,7 +166,7 @@ public class Metadata {
         * @return The name, or {@link Optional#absent()}
         */
        public Optional<String> name() {
-               return name;
+               return contentMetadata.name();
        }
 
        /**
@@ -94,7 +178,51 @@ public class Metadata {
         * @return New metadata with a changed name
         */
        public Metadata name(String name) {
-               return new Metadata(name, this.name.orNull());
+               return new Metadata(formatMetadata, contentMetadata.name(name));
+       }
+
+       /**
+        * Returns the title of the content.
+        *
+        * @return The title of the content
+        */
+       public String title() {
+               return contentMetadata.title();
+       }
+
+       /**
+        * Returns new metadata with the same attributes as this metadata but with the
+        * title changed to the given title.
+        *
+        * @param title
+        *              The new title
+        * @return The new metadata
+        */
+       public Metadata title(String title) {
+               return new Metadata(formatMetadata, contentMetadata.title(title));
+       }
+
+       //
+       // OBJECT METHODS
+       //
+
+       @Override
+       public int hashCode() {
+               return formatMetadata.hashCode() ^ contentMetadata.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object object) {
+               if (!(object instanceof Metadata)) {
+                       return false;
+               }
+               Metadata metadata = (Metadata) object;
+               return formatMetadata.equals(metadata.formatMetadata) && contentMetadata.equals(metadata.contentMetadata);
+       }
+
+       @Override
+       public String toString() {
+               return String.format("%s: %s", formatMetadata, contentMetadata);
        }
 
 }