/*************************GO-LICENSE-START*********************************
* Copyright 2014 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.domain;
import com.thoughtworks.go.util.GoConstants;
import com.thoughtworks.go.util.TimeProvider;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GoConfigRevision {
private static final String DELIMITER_CHAR = "|";
private static final String DELIMITER = "\\" + DELIMITER_CHAR;
private static final String VALUE = "(([^" + DELIMITER_CHAR + "]|" + DELIMITER + DELIMITER + ")+)";
private static final int GROUPS_IN_VALUE_MATCHER = 2; //the VALUE matcher has one subgroup per group 1 + 1 = 2
public static enum Fragment {
user, timestamp, schema_version, go_edition, go_version, md5;
public String represent(String value) {
return toString() + ":" + value;
}
private int offset() {
return ArrayUtils.indexOf(values(), this);
}
private static String string(String value, String delimiter) {
List<String> parts = new ArrayList<>(0);
for (Fragment fragment : values()) {
parts.add(fragment.represent(value));
}
return StringUtils.join(parts, delimiter);
}
private String unesc(String escapedValue) {
return escapedValue.replaceAll(DELIMITER + DELIMITER, DELIMITER_CHAR);
}
private String getMatch(Matcher matcher) {
return unesc(matcher.group(offset()*GROUPS_IN_VALUE_MATCHER + 1));
}
}
private static final Pattern PATTERN = Pattern.compile("^" + Fragment.string(VALUE, DELIMITER) + "$");
private String md5;
private String username;
private String goVersion;
private String goEdition;
private final String xml;
private Date time;
private int schemaVersion;
private String commitSHA;
public GoConfigRevision(String configXml, String md5, String username, String goVersion, TimeProvider provider) {
this(configXml);
this.md5 = md5;
this.username = username;
this.goVersion = goVersion;
this.goEdition = "OpenSource";
this.time = provider.currentTime();
this.schemaVersion = GoConstants.CONFIG_SCHEMA_VERSION;
}
public GoConfigRevision(String configXml, String comment) {
this(configXml);
Matcher matcher = PATTERN.matcher(comment);
if (matcher.matches()) {
username = Fragment.user.getMatch(matcher);
time = new Date(Long.parseLong(Fragment.timestamp.getMatch(matcher)));
schemaVersion = Integer.parseInt(Fragment.schema_version.getMatch(matcher));
goEdition = Fragment.go_edition.getMatch(matcher);
goVersion = Fragment.go_version.getMatch(matcher);
md5 = Fragment.md5.getMatch(matcher);
} else {
throw new IllegalArgumentException(String.format("failed to parse comment [%s]", comment));
}
}
private GoConfigRevision(String configXml) {
this.xml = configXml;
}
public String getMd5() {
return md5;
}
public String getContent() {
return xml;
}
public String getComment() {
return String.format(Fragment.string("%s", DELIMITER_CHAR), esc(username), esc(time.getTime()), esc(schemaVersion), esc(goEdition), esc(goVersion), esc(md5));
}
public static String esc(Object content) {
return content.toString().replaceAll(DELIMITER, DELIMITER_CHAR + DELIMITER_CHAR);
}
public String getGoVersion() {
return goVersion;
}
public String getGoEdition() {
return goEdition;
}
public String getUsername() {
return username;
}
public Date getTime() {
return time;
}
public int getSchemaVersion() {
return schemaVersion;
}
public String getCommitSHA() {
return commitSHA;
}
public void setCommitSHA(String commitSHA) {
this.commitSHA = commitSHA;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoConfigRevision that = (GoConfigRevision) o;
if (md5 != null ? !md5.equals(that.md5) : that.md5 != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
return md5 != null ? md5.hashCode() : 0;
}
@Override public String toString() {
return new ToStringBuilder(this).
append("time", time).
append("md5", md5).
append("username", username).
append("goVersion", goVersion).
append("goEdition", goEdition).
append("xml", xml).
append("schemaVersion", schemaVersion).
toString();
}
}