Make CommentLinkInfoImpl an AutoValue and remove inheritance
CommentLinkInfoImpl used to inherit from CommentLinkInfo because
that makes it easy to parse it from project.config. At the same
time, it means that the entity will always be mutable. Since we
cache it in ProjectCache, that is undesired.
This commit makes it an AutoValue and removes any inheritance
using trivial replacements with values.
While at it, rename the class to StoredCommentLinkInfo
Change-Id: I630d7f8957f4a24dd4f6a6dfbbdf73f3542b00fd
diff --git a/java/com/google/gerrit/server/project/CommentLinkInfoImpl.java b/java/com/google/gerrit/server/project/CommentLinkInfoImpl.java
deleted file mode 100644
index 35de963..0000000
--- a/java/com/google/gerrit/server/project/CommentLinkInfoImpl.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2012 The Android Open Source Project
-//
-// 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.
-
-package com.google.gerrit.server.project;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Strings;
-import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
-
-/** Info about a single commentlink section in a config. */
-public class CommentLinkInfoImpl extends CommentLinkInfo {
- public static class Enabled extends CommentLinkInfoImpl {
- public Enabled(String name) {
- super(name, true);
- }
-
- @Override
- boolean isOverrideOnly() {
- return true;
- }
- }
-
- public static class Disabled extends CommentLinkInfoImpl {
- public Disabled(String name) {
- super(name, false);
- }
-
- @Override
- boolean isOverrideOnly() {
- return true;
- }
- }
-
- public CommentLinkInfoImpl(String name, String match, String link, String html, Boolean enabled) {
- checkArgument(name != null, "invalid commentlink.name");
- checkArgument(!Strings.isNullOrEmpty(match), "invalid commentlink.%s.match", name);
- link = Strings.emptyToNull(link);
- html = Strings.emptyToNull(html);
- checkArgument(
- (link != null && html == null) || (link == null && html != null),
- "commentlink.%s must have either link or html",
- name);
- this.name = name;
- this.match = match;
- this.link = link;
- this.html = html;
- this.enabled = enabled;
- }
-
- private CommentLinkInfoImpl(CommentLinkInfo src, boolean enabled) {
- this.name = src.name;
- this.match = src.match;
- this.link = src.link;
- this.html = src.html;
- this.enabled = enabled;
- }
-
- private CommentLinkInfoImpl(String name, boolean enabled) {
- this.name = name;
- this.match = null;
- this.link = null;
- this.html = null;
- this.enabled = enabled;
- }
-
- boolean isOverrideOnly() {
- return false;
- }
-
- CommentLinkInfo inherit(CommentLinkInfo src) {
- return new CommentLinkInfoImpl(src, enabled);
- }
-}
diff --git a/java/com/google/gerrit/server/project/CommentLinkProvider.java b/java/com/google/gerrit/server/project/CommentLinkProvider.java
index 4987d00..500e163 100644
--- a/java/com/google/gerrit/server/project/CommentLinkProvider.java
+++ b/java/com/google/gerrit/server/project/CommentLinkProvider.java
@@ -47,12 +47,12 @@
List<CommentLinkInfo> cls = Lists.newArrayListWithCapacity(subsections.size());
for (String name : subsections) {
try {
- CommentLinkInfoImpl cl = ProjectConfig.buildCommentLink(cfg, name, true);
- if (cl.isOverrideOnly()) {
+ StoredCommentLinkInfo cl = ProjectConfig.buildCommentLink(cfg, name, true);
+ if (cl.getOverrideOnly()) {
logger.atWarning().log("commentlink %s empty except for \"enabled\"", name);
continue;
}
- cls.add(cl);
+ cls.add(cl.toInfo());
} catch (IllegalArgumentException e) {
logger.atWarning().log("invalid commentlink: %s", e.getMessage());
}
diff --git a/java/com/google/gerrit/server/project/ProjectConfig.java b/java/com/google/gerrit/server/project/ProjectConfig.java
index 0deb25d..e8f8dc1 100644
--- a/java/com/google/gerrit/server/project/ProjectConfig.java
+++ b/java/com/google/gerrit/server/project/ProjectConfig.java
@@ -241,7 +241,7 @@
private Map<String, LabelType> labelSections;
private ConfiguredMimeTypes mimeTypes;
private Map<Project.NameKey, SubscribeSection> subscribeSections;
- private Map<String, CommentLinkInfoImpl> commentLinkSections;
+ private Map<String, StoredCommentLinkInfo> commentLinkSections;
private List<ValidationError> validationErrors;
private ObjectId rulesId;
private long maxObjectSizeLimit;
@@ -251,7 +251,7 @@
private boolean hasLegacyPermissions;
private Map<String, List<String>> extensionPanelSections;
- public static CommentLinkInfoImpl buildCommentLink(Config cfg, String name, boolean allowRaw)
+ public static StoredCommentLinkInfo buildCommentLink(Config cfg, String name, boolean allowRaw)
throws IllegalArgumentException {
String match = cfg.getString(COMMENTLINK, name, KEY_MATCH);
if (match != null) {
@@ -281,15 +281,21 @@
&& !hasHtml
&& enabled != null) {
if (enabled) {
- return new CommentLinkInfoImpl.Enabled(name);
+ return StoredCommentLinkInfo.enabled(name);
}
- return new CommentLinkInfoImpl.Disabled(name);
+ return StoredCommentLinkInfo.disabled(name);
}
- return new CommentLinkInfoImpl(name, match, link, html, enabled);
+ return StoredCommentLinkInfo.builder(name)
+ .setMatch(match)
+ .setLink(link)
+ .setHtml(html)
+ .setEnabled(enabled)
+ .setOverrideOnly(false)
+ .build();
}
- public void addCommentLinkSection(CommentLinkInfoImpl commentLink) {
- commentLinkSections.put(commentLink.name, commentLink);
+ public void addCommentLinkSection(StoredCommentLinkInfo commentLink) {
+ commentLinkSections.put(commentLink.getName(), commentLink);
}
public void removeCommentLinkSection(String name) {
@@ -479,7 +485,7 @@
return labelSections;
}
- public Collection<CommentLinkInfoImpl> getCommentLinkSections() {
+ public Collection<StoredCommentLinkInfo> getCommentLinkSections() {
return commentLinkSections.values();
}
@@ -1235,16 +1241,16 @@
private void saveCommentLinkSections(Config rc) {
unsetSection(rc, COMMENTLINK);
if (commentLinkSections != null) {
- for (CommentLinkInfoImpl cm : commentLinkSections.values()) {
- rc.setString(COMMENTLINK, cm.name, KEY_MATCH, cm.match);
- if (!Strings.isNullOrEmpty(cm.html)) {
- rc.setString(COMMENTLINK, cm.name, KEY_HTML, cm.html);
+ for (StoredCommentLinkInfo cm : commentLinkSections.values()) {
+ rc.setString(COMMENTLINK, cm.getName(), KEY_MATCH, cm.getMatch());
+ if (!Strings.isNullOrEmpty(cm.getHtml())) {
+ rc.setString(COMMENTLINK, cm.getName(), KEY_HTML, cm.getHtml());
}
- if (!Strings.isNullOrEmpty(cm.link)) {
- rc.setString(COMMENTLINK, cm.name, KEY_LINK, cm.link);
+ if (!Strings.isNullOrEmpty(cm.getLink())) {
+ rc.setString(COMMENTLINK, cm.getName(), KEY_LINK, cm.getLink());
}
- if (cm.enabled != null && !cm.enabled) {
- rc.setBoolean(COMMENTLINK, cm.name, KEY_ENABLED, cm.enabled);
+ if (cm.getEnabled() != null && !cm.getEnabled()) {
+ rc.setBoolean(COMMENTLINK, cm.getName(), KEY_ENABLED, cm.getEnabled());
}
}
}
diff --git a/java/com/google/gerrit/server/project/ProjectState.java b/java/com/google/gerrit/server/project/ProjectState.java
index efadcc8..1c7c7d6 100644
--- a/java/com/google/gerrit/server/project/ProjectState.java
+++ b/java/com/google/gerrit/server/project/ProjectState.java
@@ -457,16 +457,16 @@
cls.put(cl.name.toLowerCase(), cl);
}
for (ProjectState s : treeInOrder()) {
- for (CommentLinkInfoImpl cl : s.getConfig().getCommentLinkSections()) {
- String name = cl.name.toLowerCase();
- if (cl.isOverrideOnly()) {
+ for (StoredCommentLinkInfo cl : s.getConfig().getCommentLinkSections()) {
+ String name = cl.getName().toLowerCase();
+ if (cl.getOverrideOnly()) {
CommentLinkInfo parent = cls.get(name);
if (parent == null) {
continue; // Ignore invalid overrides.
}
- cls.put(name, cl.inherit(parent));
+ cls.put(name, StoredCommentLinkInfo.fromInfo(parent, cl.getEnabled()).toInfo());
} else {
- cls.put(name, cl);
+ cls.put(name, cl.toInfo());
}
}
}
diff --git a/java/com/google/gerrit/server/project/StoredCommentLinkInfo.java b/java/com/google/gerrit/server/project/StoredCommentLinkInfo.java
new file mode 100644
index 0000000..4e311b8
--- /dev/null
+++ b/java/com/google/gerrit/server/project/StoredCommentLinkInfo.java
@@ -0,0 +1,133 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.
+
+package com.google.gerrit.server.project;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Strings;
+import com.google.gerrit.common.Nullable;
+import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
+
+/** Info about a single commentlink section in a config. */
+@AutoValue
+public abstract class StoredCommentLinkInfo {
+ public abstract String getName();
+
+ /** A regular expression to match for the commentlink to apply. */
+ @Nullable
+ public abstract String getMatch();
+
+ /** The link to replace the match with. This can only be set if html is {@code null}. */
+ @Nullable
+ public abstract String getLink();
+
+ /** The html to replace the match with. This can only be set if link is {@code null}. */
+ @Nullable
+ public abstract String getHtml();
+
+ /** Weather this comment link is active. {@code null} means true. */
+ @Nullable
+ public abstract Boolean getEnabled();
+
+ /** If set, {@link StoredCommentLinkInfo} has to be overriden to take any effect. */
+ public abstract boolean getOverrideOnly();
+
+ /**
+ * Creates an enabled {@link StoredCommentLinkInfo} that can be overriden but doesn't do anything
+ * on its own.
+ */
+ public static StoredCommentLinkInfo enabled(String name) {
+ return builder(name).setOverrideOnly(true).build();
+ }
+
+ /**
+ * Creates a disabled {@link StoredCommentLinkInfo} that can be overriden but doesn't do anything
+ * on it's own.
+ */
+ public static StoredCommentLinkInfo disabled(String name) {
+ return builder(name).setOverrideOnly(true).build();
+ }
+
+ /** Creates and returns a new {@link StoredCommentLinkInfo.Builder} instance. */
+ public static Builder builder(String name) {
+ checkArgument(name != null, "invalid commentlink.name");
+ return new AutoValue_StoredCommentLinkInfo.Builder().setName(name).setOverrideOnly(false);
+ }
+
+ /** Creates and returns a new {@link StoredCommentLinkInfo} instance with the same values. */
+ static StoredCommentLinkInfo fromInfo(CommentLinkInfo src, boolean enabled) {
+ return builder(src.name)
+ .setMatch(src.match)
+ .setLink(src.link)
+ .setHtml(src.html)
+ .setEnabled(enabled)
+ .setOverrideOnly(false)
+ .build();
+ }
+
+ /** Returns an {@link CommentLinkInfo} instance with the same values. */
+ CommentLinkInfo toInfo() {
+ CommentLinkInfo info = new CommentLinkInfo();
+ info.name = getName();
+ info.match = getMatch();
+ info.link = getLink();
+ info.html = getHtml();
+ info.enabled = getEnabled();
+ return info;
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder setName(String value);
+
+ public abstract Builder setMatch(@Nullable String value);
+
+ public abstract Builder setLink(@Nullable String value);
+
+ public abstract Builder setHtml(@Nullable String value);
+
+ public abstract Builder setEnabled(@Nullable Boolean value);
+
+ public abstract Builder setOverrideOnly(boolean value);
+
+ public StoredCommentLinkInfo build() {
+ checkArgument(getName() != null, "invalid commentlink.name");
+ setLink(Strings.emptyToNull(getLink()));
+ setHtml(Strings.emptyToNull(getHtml()));
+ if (!getOverrideOnly()) {
+ checkArgument(
+ !Strings.isNullOrEmpty(getMatch()), "invalid commentlink.%s.match", getName());
+ checkArgument(
+ (getLink() != null && getHtml() == null) || (getLink() == null && getHtml() != null),
+ "commentlink.%s must have either link or html",
+ getName());
+ }
+ return autoBuild();
+ }
+
+ protected abstract StoredCommentLinkInfo autoBuild();
+
+ protected abstract String getName();
+
+ protected abstract String getMatch();
+
+ protected abstract String getLink();
+
+ protected abstract String getHtml();
+
+ protected abstract boolean getOverrideOnly();
+ }
+}
diff --git a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
index 8dc76dd..cb22849 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
@@ -64,7 +64,6 @@
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.config.ProjectConfigEntry;
import com.google.gerrit.server.group.SystemGroupBackend;
-import com.google.gerrit.server.project.CommentLinkInfoImpl;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
@@ -916,7 +915,11 @@
}
private CommentLinkInfo commentLinkInfo(String name, String match, String link) {
- return new CommentLinkInfoImpl(name, match, link, null /*html*/, null /*enabled*/);
+ CommentLinkInfo info = new CommentLinkInfo();
+ info.name = name;
+ info.match = match;
+ info.link = link;
+ return info;
}
private void assertCommentLinks(ConfigInfo actual, Map<String, CommentLinkInfo> expected) {
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index a8ea686..214aae7 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -392,7 +392,13 @@
update(rev);
ProjectConfig cfg = read(rev);
- CommentLinkInfoImpl cm = new CommentLinkInfoImpl("Test", "abc.*", null, "<a>link</a>", true);
+ StoredCommentLinkInfo cm =
+ StoredCommentLinkInfo.builder("Test")
+ .setMatch("abc.*")
+ .setHtml("<a>link</a>")
+ .setEnabled(true)
+ .setOverrideOnly(false)
+ .build();
cfg.addCommentLinkSection(cm);
rev = commit(cfg);
assertThat(text(rev, "project.config"))
@@ -555,12 +561,11 @@
ProjectConfig cfg = read(rev);
assertThat(cfg.getCommentLinkSections())
.containsExactly(
- new CommentLinkInfoImpl(
- "bugzilla",
- "(bug\\s+#?)(\\d+)",
- "http://bugs.example.com/show_bug.cgi?id=$2",
- null,
- null));
+ StoredCommentLinkInfo.builder("bugzilla")
+ .setMatch("(bug\\s+#?)(\\d+)")
+ .setLink("http://bugs.example.com/show_bug.cgi?id=$2")
+ .setOverrideOnly(false)
+ .build());
}
@Test
@@ -569,7 +574,7 @@
tr.commit().add("project.config", "[commentlink \"bugzilla\"]\n \tenabled = true").create();
ProjectConfig cfg = read(rev);
assertThat(cfg.getCommentLinkSections())
- .containsExactly(new CommentLinkInfoImpl.Enabled("bugzilla"));
+ .containsExactly(StoredCommentLinkInfo.enabled("bugzilla"));
}
@Test
@@ -580,7 +585,7 @@
.create();
ProjectConfig cfg = read(rev);
assertThat(cfg.getCommentLinkSections())
- .containsExactly(new CommentLinkInfoImpl.Disabled("bugzilla"));
+ .containsExactly(StoredCommentLinkInfo.disabled("bugzilla"));
}
@Test