001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * SonarQube is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.api.notifications;
021    
022    import com.google.common.collect.Maps;
023    import org.apache.commons.lang.builder.ReflectionToStringBuilder;
024    import org.apache.commons.lang.builder.ToStringStyle;
025    
026    import javax.annotation.CheckForNull;
027    import javax.annotation.Nullable;
028    import java.io.Serializable;
029    import java.util.Map;
030    
031    /**
032     * <p>
033     * This class represents a notification that will be delivered to users. This is a general concept and it has no
034     * knowledge of the possible ways to be delivered (see {@link NotificationChannel}) or of the users who should
035     * receive it (see {@link NotificationDispatcher}).
036     * </p>
037     * <p>
038     * When creating a new notification, it is strongly advised to give a default message that can be  used by channels
039     * that don't want to specifically format messages for different notification types. You can use
040     * {@link Notification#setDefaultMessage(String)} for that purpose.
041     * </p>
042     *
043     * @since 2.10
044     */
045    public class Notification implements Serializable {
046    
047      private static final String DEFAULT_MESSAGE_KEY = "default_message";
048    
049      private final String type;
050      private final Map<String, String> fields = Maps.newHashMap();
051    
052      /**
053       * <p>
054       * Create a new {@link Notification} of the given type.
055       * </p>
056       * Example: type = "new-violations"
057       *
058       * @param type the type of notification
059       */
060      public Notification(String type) {
061        this.type = type;
062      }
063    
064      /**
065       * Returns the type of the notification
066       *
067       * @return the type
068       */
069      public String getType() {
070        return type;
071      }
072    
073      /**
074       * <p>
075       * When creating a new notification, it is strongly advised to give a default message that can be
076       * used by channels that don't want to specifically format messages for different notification types.
077       * </p>
078       * <p>
079       * This method is equivalent to setting a value for the field {@link #DEFAULT_MESSAGE_KEY} with
080       * {@link #setFieldValue(String, String)}.
081       * </p>
082       *
083       * @since 3.5
084       */
085      public Notification setDefaultMessage(String value) {
086        setFieldValue(DEFAULT_MESSAGE_KEY, value);
087        return this;
088      }
089    
090      /**
091       * Returns the default message to display for this notification.
092       */
093      public String getDefaultMessage() {
094        String defaultMessage = getFieldValue(DEFAULT_MESSAGE_KEY);
095        if (defaultMessage == null) {
096          defaultMessage = this.toString();
097        }
098        return defaultMessage;
099      }
100    
101      /**
102       * Adds a field (kind of property) to the notification
103       *
104       * @param field the name of the field (= the key)
105       * @param value the value of the field
106       * @return the notification itself
107       */
108      public Notification setFieldValue(String field, @Nullable String value) {
109        fields.put(field, value);
110        return this;
111      }
112    
113      /**
114       * Returns the value of a field.
115       *
116       * @param field the field
117       * @return the value of the field
118       */
119      @CheckForNull
120      public String getFieldValue(String field) {
121        return fields.get(field);
122      }
123    
124      @Override
125      public boolean equals(Object obj) {
126        if (!(obj instanceof Notification)) {
127          return false;
128        }
129        if (this == obj) {
130          return true;
131        }
132        Notification other = (Notification) obj;
133        return this.type.equals(other.type) && this.fields.equals(other.fields);
134      }
135    
136      @Override
137      public int hashCode() {
138        return type.hashCode() * 31 + fields.hashCode();
139      }
140    
141      @Override
142      public String toString() {
143        return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
144      }
145    
146    }