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 */
020package org.sonar.api.issue.internal;
021
022import com.google.common.base.Splitter;
023import com.google.common.base.Strings;
024import com.google.common.collect.Maps;
025
026import javax.annotation.CheckForNull;
027import javax.annotation.Nullable;
028import java.io.Serializable;
029import java.util.Date;
030import java.util.Map;
031
032/**
033 * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
034 *
035 * @since 3.6
036 */
037public 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}