001/**
002 *
003 * Copyright 2019 Aditya Borikar.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.usertune.element;
018
019import java.net.URI;
020
021import javax.xml.namespace.QName;
022
023import org.jivesoftware.smack.datatypes.UInt16;
024import org.jivesoftware.smack.packet.ExtensionElement;
025import org.jivesoftware.smack.packet.Message;
026import org.jivesoftware.smack.packet.XmlEnvironment;
027import org.jivesoftware.smack.util.EqualsUtil;
028import org.jivesoftware.smack.util.HashCode;
029import org.jivesoftware.smack.util.XmlStringBuilder;
030
031/**
032 * {@link ExtensionElement} that contains the UserTune. <br>
033 * Instance of UserTuneElement can be created using {@link Builder#build()}
034 * method.
035 */
036public final class UserTuneElement implements ExtensionElement {
037
038    public static final String NAMESPACE = "http://jabber.org/protocol/tune";
039    public static final String ELEMENT = "tune";
040    public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
041
042    private final String artist;
043    private final UInt16 length;
044    private final Integer rating;
045    private final String source;
046    private final String title;
047    private final String track;
048    private final URI uri;
049
050    public static final UserTuneElement EMPTY_USER_TUNE = null;
051
052    private UserTuneElement(Builder builder) {
053        this.artist = builder.artist;
054        this.length = builder.length;
055        this.rating = builder.rating;
056        this.source = builder.source;
057        this.title = builder.title;
058        this.track = builder.track;
059        this.uri = builder.uri;
060    }
061
062    @Override
063    public String getNamespace() {
064        return NAMESPACE;
065    }
066
067    @Override
068    public String getElementName() {
069        return ELEMENT;
070    }
071
072    public String getArtist() {
073        return artist;
074    }
075
076    public UInt16 getLength() {
077        return length;
078    }
079
080    public Integer getRating() {
081        return rating;
082    }
083
084    public String getSource() {
085        return source;
086    }
087
088    public String getTitle() {
089        return title;
090    }
091
092    public String getTrack() {
093        return track;
094    }
095
096    public URI getUri() {
097        return uri;
098    }
099
100    @Override
101    public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) {
102        XmlStringBuilder xml = new XmlStringBuilder(this);
103        if (isEmptyUserTune()) {
104            return xml.closeEmptyElement();
105        }
106        xml.rightAngleBracket();
107        xml.optElement("artist", artist);
108        xml.optElement("length", length);
109        xml.optElement("rating", rating);
110        xml.optElement("source", source);
111        xml.optElement("title", title);
112        xml.optElement("track", track);
113        xml.optElement("uri", uri);
114        return xml.closeElement(getElementName());
115    }
116
117    private boolean isEmptyUserTune() {
118        return this.equals(EMPTY_USER_TUNE);
119    }
120
121    public static boolean hasUserTuneElement(Message message) {
122        return message.hasExtension(UserTuneElement.class);
123    }
124
125    public static UserTuneElement from(Message message) {
126        return message.getExtension(UserTuneElement.class);
127    }
128
129    @Override
130    public int hashCode() {
131        return HashCode.builder()
132                .append(artist)
133                .append(length)
134                .append(rating)
135                .append(source)
136                .append(title)
137                .append(track)
138                .append(uri).build();
139    }
140
141    @Override
142    public boolean equals(Object obj) {
143        return EqualsUtil
144                .equals(this, obj, (equalsBuilder, otherTune) -> equalsBuilder
145                                                            .append(artist, otherTune.artist)
146                                                            .append(length, otherTune.length)
147                                                            .append(rating, otherTune.rating)
148                                                            .append(source, otherTune.source)
149                                                            .append(title, otherTune.title)
150                                                            .append(track, otherTune.track)
151                                                            .append(uri, otherTune.uri));
152    }
153
154    /**
155     * Returns a new instance of {@link Builder}.
156     * @return Builder
157     */
158    public static Builder getBuilder() {
159        return new Builder();
160    }
161
162    /**
163     * This class defines a Builder class for {@link UserTuneElement}. <br>
164     * {@link UserTuneElement} instance can be obtained using the {@link #build()} method as follows. <br><br>
165     * <pre>
166     * {@code
167     * UserTuneElement.Builder builder = UserTuneElement.getBuilder();
168     * builder.setSource("Yessongs");
169     * builder.setTitle("Heart of the Sunrise");
170     * UserTuneElement userTuneElement = builder.build();
171     * }
172     * </pre>
173     * Values such as title, source, artist, length, source, track and uri can be set using their respective setters through {@link Builder}.
174     */
175    public static final class Builder {
176        private String artist;
177        private UInt16 length;
178        private Integer rating;
179        private String source;
180        private String title;
181        private String track;
182        private URI uri;
183
184        private Builder() {
185        }
186
187        /**
188         * Artist is an optional element in UserTuneElement.
189         * @param artist the artist.
190         * @return a reference to this builder.
191         */
192        public Builder setArtist(String artist) {
193            this.artist = artist;
194            return this;
195        }
196
197        /**
198         * Length is an optional element in UserTuneElement.
199         * @param length the length.
200         * @return a reference to this builder.
201         */
202        public Builder setLength(int length) {
203            return setLength(UInt16.from(length));
204        }
205
206        /**
207         * Length is an optional element in UserTuneElement.
208         * @param length the length.
209         * @return a reference to this builder.
210         */
211        public Builder setLength(UInt16 length) {
212            this.length = length;
213            return this;
214        }
215
216        /**
217         * Rating is an optional element in UserTuneElement.
218         * @param rating the rating.
219         * @return a reference to this builder.
220         */
221        public Builder setRating(int rating) {
222            this.rating = rating;
223            return this;
224        }
225
226        /**
227         * Source is an optional element in UserTuneElement.
228         * @param source the source.
229         * @return a reference to this builder.
230         */
231        public Builder setSource(String source) {
232            this.source = source;
233            return this;
234        }
235
236        /**
237         * Title is an optional element in UserTuneElement.
238         * @param title the title.
239         * @return a reference to this builder.
240         */
241        public Builder setTitle(String title) {
242            this.title = title;
243            return this;
244        }
245
246        /**
247         * Track is an optional element in UserTuneElement.
248         * @param track the track.
249         * @return a reference to this builder.
250         */
251        public Builder setTrack(String track) {
252            this.track = track;
253            return this;
254        }
255
256        /**
257         * URI is an optional element in UserTuneElement.
258         * @param uri the URI.
259         * @return a reference to this builder.
260         */
261        public Builder setUri(URI uri) {
262            this.uri = uri;
263            return this;
264        }
265
266        /**
267         * This method is called to build a UserTuneElement.
268         * @return UserTuneElement.
269         */
270        public UserTuneElement build() {
271            return new UserTuneElement(this);
272        }
273    }
274}