001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2013 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.issue.internal;
021    
022    import com.google.common.base.Splitter;
023    import com.google.common.base.Strings;
024    import com.google.common.collect.Maps;
025    
026    import javax.annotation.CheckForNull;
027    import javax.annotation.Nullable;
028    import java.io.Serializable;
029    import java.util.Date;
030    import java.util.Map;
031    
032    /**
033     * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
034     *
035     * @since 3.6
036     */
037    public class FieldDiffs implements Serializable {
038    
039      public static final Splitter FIELDS_SPLITTER = Splitter.on(',').omitEmptyStrings();
040    
041      private String userLogin;
042      private Date createdAt, updatedAt;
043      private final Map<String, Diff> diffs = Maps.newLinkedHashMap();
044    
045      public Map<String, Diff> diffs() {
046        return diffs;
047      }
048    
049      public Diff get(String field) {
050        return diffs.get(field);
051      }
052    
053      @CheckForNull
054      public String userLogin() {
055        return userLogin;
056      }
057    
058      public FieldDiffs setUserLogin(@Nullable String s) {
059        this.userLogin = s;
060        return this;
061      }
062    
063      public Date createdAt() {
064        return createdAt;
065      }
066    
067      public FieldDiffs setCreatedAt(Date d) {
068        this.createdAt = d;
069        return this;
070      }
071    
072      public Date updatedAt() {
073        return updatedAt;
074      }
075    
076      public FieldDiffs setUpdatedAt(Date d) {
077        this.updatedAt = d;
078        return this;
079      }
080    
081    
082      @SuppressWarnings("unchecked")
083      public FieldDiffs setDiff(String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) {
084        Diff diff = diffs.get(field);
085        if (diff == null) {
086          diff = new Diff(oldValue, newValue);
087          diffs.put(field, diff);
088        } else {
089          diff.setNewValue(newValue);
090        }
091        return this;
092      }
093    
094      @Override
095      public String toString() {
096        StringBuilder sb = new StringBuilder();
097        boolean notFirst = false;
098        for (Map.Entry<String, Diff> entry : diffs.entrySet()) {
099          if (notFirst) {
100            sb.append(',');
101          } else {
102            notFirst = true;
103          }
104          sb.append(entry.getKey());
105          sb.append('=');
106          sb.append(entry.getValue().toString());
107        }
108        return sb.toString();
109      }
110    
111      public static FieldDiffs parse(@Nullable String s) {
112        FieldDiffs diffs = new FieldDiffs();
113        if (!Strings.isNullOrEmpty(s)) {
114          Iterable<String> fields = FIELDS_SPLITTER.split(s);
115          for (String field : fields) {
116            String[] keyValues = field.split("=");
117            if (keyValues.length == 2) {
118              String[] values = keyValues[1].split("\\|");
119              String oldValue = "";
120              String newValue = "";
121              if (values.length > 0) {
122                oldValue = Strings.nullToEmpty(values[0]);
123              }
124              if (values.length > 1) {
125                newValue = Strings.nullToEmpty(values[1]);
126              }
127              diffs.setDiff(keyValues[0], oldValue, newValue);
128            }
129          }
130        }
131        return diffs;
132      }
133    
134      public static class Diff<T extends Serializable> implements Serializable {
135        private T oldValue, newValue;
136    
137        public Diff(@Nullable T oldValue, @Nullable T newValue) {
138          this.oldValue = oldValue;
139          this.newValue = newValue;
140        }
141    
142        public T oldValue() {
143          return oldValue;
144        }
145    
146        public T newValue() {
147          return newValue;
148        }
149    
150        void setNewValue(T t) {
151          this.newValue = t;
152        }
153    
154        @Override
155        public String toString() {
156          //TODO escape , and | characters
157          StringBuilder sb = new StringBuilder();
158          if (oldValue != null) {
159            sb.append(oldValue.toString());
160          }
161          sb.append('|');
162          if (newValue != null) {
163            sb.append(newValue.toString());
164          }
165          return sb.toString();
166        }
167      }
168    }