Add serializer for ConfiguredMimeType

This commit adds a serializer for the ConfiguredMimeType entitiy.
The eventual goal is that we serialize CachedProjectConfig. The
entity is too large to be serialized directly, though, so we
divide and conquer.

This commit moves the AutoValue representation to the entities
package to allow the serializer packages to keep its dependencies
minimal.

Change-Id: I524ee5fe0358ebefa05b4a1fb24fd34631ef721d
This commit is contained in:
Patrick Hiesel
2020-07-16 10:17:59 +02:00
parent 4938bda71e
commit 7e579e3a39
7 changed files with 138 additions and 10 deletions

View File

@@ -16,6 +16,7 @@ java_library(
"//lib/auto:auto-value",
"//lib/auto:auto-value-annotations",
"//lib/errorprone:annotations",
"//lib/flogger:api",
"//proto:cache_java_proto",
"//proto:entities_java_proto",
],

View File

@@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.project;
package com.google.gerrit.entities;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -34,7 +35,7 @@ public abstract class ConfiguredMimeTypes {
protected abstract ImmutableList<TypeMatcher> matchers();
static ConfiguredMimeTypes create(String projectName, Config rc) {
public static ConfiguredMimeTypes create(String projectName, Config rc) {
Set<String> types = rc.getSubsections(MIMETYPE);
ImmutableList.Builder<TypeMatcher> matchers = ImmutableList.builder();
if (!types.isEmpty()) {
@@ -67,21 +68,31 @@ public abstract class ConfiguredMimeTypes {
return null;
}
protected abstract static class TypeMatcher {
public abstract static class TypeMatcher {
private final String type;
private final String pattern;
private TypeMatcher(String type) {
private TypeMatcher(String type, String pattern) {
this.type = type;
this.pattern = pattern;
}
public String getPattern() {
return pattern;
}
public String getType() {
return type;
}
protected abstract boolean matches(String path);
}
protected static class FnType extends TypeMatcher {
public static class FnType extends TypeMatcher {
private final FileNameMatcher matcher;
private FnType(String type, String pattern) throws InvalidPatternException {
super(type);
public FnType(String type, String pattern) throws InvalidPatternException {
super(type, pattern);
this.matcher = new FileNameMatcher(pattern, null);
}
@@ -91,13 +102,28 @@ public abstract class ConfiguredMimeTypes {
m.append(input);
return m.isMatch();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof FnType)) {
return false;
}
FnType other = (FnType) o;
return Objects.equals(other.getType(), getType())
&& Objects.equals(other.getPattern(), getPattern());
}
@Override
public int hashCode() {
return Objects.hash(getType(), getPattern());
}
}
protected static class ReType extends TypeMatcher {
public static class ReType extends TypeMatcher {
private final Pattern re;
private ReType(String type, String pattern) throws PatternSyntaxException {
super(type);
public ReType(String type, String pattern) throws PatternSyntaxException {
super(type, pattern);
this.re = Pattern.compile(pattern);
}
@@ -105,5 +131,20 @@ public abstract class ConfiguredMimeTypes {
protected boolean matches(String input) {
return re.matcher(input).matches();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ReType)) {
return false;
}
ReType other = (ReType) o;
return Objects.equals(other.getType(), getType())
&& Objects.equals(other.getPattern(), getPattern());
}
@Override
public int hashCode() {
return Objects.hash(getType(), getPattern());
}
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (C) 2020 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.cache.serialize.entities;
import com.google.gerrit.entities.ConfiguredMimeTypes;
import com.google.gerrit.server.cache.proto.Cache;
import java.util.regex.PatternSyntaxException;
import org.eclipse.jgit.errors.InvalidPatternException;
public class ConfiguredMimeTypeSerializer {
public static ConfiguredMimeTypes.TypeMatcher deserialize(Cache.ConfiguredMimeTypeProto proto) {
try {
return proto.getIsRegularExpression()
? new ConfiguredMimeTypes.ReType(proto.getType(), proto.getPattern())
: new ConfiguredMimeTypes.FnType(proto.getType(), proto.getPattern());
} catch (PatternSyntaxException | InvalidPatternException e) {
throw new IllegalStateException(e);
}
}
public static Cache.ConfiguredMimeTypeProto serialize(ConfiguredMimeTypes.TypeMatcher value) {
return Cache.ConfiguredMimeTypeProto.newBuilder()
.setType(value.getType())
.setPattern(value.getPattern())
.setIsRegularExpression(value instanceof ConfiguredMimeTypes.ReType)
.build();
}
}

View File

@@ -25,6 +25,7 @@ import com.google.gerrit.common.data.SubscribeSection;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.BranchOrderSection;
import com.google.gerrit.entities.ConfiguredMimeTypes;
import com.google.gerrit.entities.GroupReference;
import com.google.gerrit.entities.NotifyConfig;
import com.google.gerrit.entities.Project;

View File

@@ -46,6 +46,7 @@ import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.Address;
import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchOrderSection;
import com.google.gerrit.entities.ConfiguredMimeTypes;
import com.google.gerrit.entities.GroupDescription;
import com.google.gerrit.entities.GroupReference;
import com.google.gerrit.entities.LabelValue;

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2020 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.cache.serialize.entities;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.cache.serialize.entities.ConfiguredMimeTypeSerializer.deserialize;
import static com.google.gerrit.server.cache.serialize.entities.ConfiguredMimeTypeSerializer.serialize;
import com.google.gerrit.entities.ConfiguredMimeTypes;
import org.junit.Test;
public class ConfiguredMimeTypeSerializerTest {
@Test
public void reType_roundTrip() {
ConfiguredMimeTypes.ReType value = new ConfiguredMimeTypes.ReType("type", "pattern");
assertThat(deserialize(serialize(value))).isEqualTo(value);
}
@Test
public void fnType_roundTrip() throws Exception {
ConfiguredMimeTypes.FnType value = new ConfiguredMimeTypes.FnType("type", "pattern");
assertThat(deserialize(serialize(value))).isEqualTo(value);
}
}

View File

@@ -436,3 +436,11 @@ message LabelTypeProto {
bool can_override = 17;
repeated string ref_patterns = 18;
}
// Serialized form of com.google.gerrit.server.project.ConfiguredMimeTypes.
// Next ID: 4
message ConfiguredMimeTypeProto {
string type = 1;
string pattern = 2;
bool is_regular_expression = 3;
}