Line data Source code
1 : // Copyright (C) 2016 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.index; 16 : 17 : import static com.google.common.base.Preconditions.checkArgument; 18 : 19 : import com.google.common.base.CharMatcher; 20 : import com.google.common.base.Splitter; 21 : import com.google.common.collect.ImmutableList; 22 : import com.google.common.collect.ImmutableSet; 23 : import com.google.common.collect.ImmutableSortedMap; 24 : import com.google.common.collect.Iterables; 25 : import java.lang.reflect.Field; 26 : import java.lang.reflect.Modifier; 27 : import java.lang.reflect.ParameterizedType; 28 : import java.util.Collections; 29 : import java.util.HashMap; 30 : import java.util.HashSet; 31 : import java.util.Locale; 32 : import java.util.Map; 33 : import java.util.Set; 34 : import org.eclipse.jgit.lib.PersonIdent; 35 : 36 : public class SchemaUtil { 37 : public static <V> ImmutableSortedMap<Integer, Schema<V>> schemasFromClass( 38 : Class<?> schemasClass, Class<V> valueClass) { 39 154 : Map<Integer, Schema<V>> schemas = new HashMap<>(); 40 154 : for (Field f : schemasClass.getDeclaredFields()) { 41 154 : if (Modifier.isStatic(f.getModifiers()) 42 154 : && Modifier.isFinal(f.getModifiers()) 43 154 : && Schema.class.isAssignableFrom(f.getType())) { 44 154 : ParameterizedType t = (ParameterizedType) f.getGenericType(); 45 154 : if (t.getActualTypeArguments()[0] == valueClass) { 46 : try { 47 154 : f.setAccessible(true); 48 : @SuppressWarnings("unchecked") 49 154 : Schema<V> schema = (Schema<V>) f.get(null); 50 154 : checkArgument(f.getName().startsWith("V")); 51 154 : int versionName = Integer.parseInt(f.getName().substring(1)); 52 154 : checkArgument( 53 154 : versionName == schema.getVersion(), 54 : "Schema version %s does not match its name %s", 55 154 : schema.getVersion(), 56 154 : f.getName()); 57 154 : schemas.put(schema.getVersion(), schema); 58 0 : } catch (IllegalAccessException e) { 59 0 : throw new IllegalArgumentException(e); 60 154 : } 61 : } else { 62 1 : throw new IllegalArgumentException( 63 1 : "non-" + schemasClass.getSimpleName() + " schema: " + f); 64 : } 65 : } 66 : } 67 154 : if (schemas.isEmpty()) { 68 0 : throw new ExceptionInInitializerError("no ChangeSchemas found"); 69 : } 70 154 : return ImmutableSortedMap.copyOf(schemas); 71 : } 72 : 73 : @SafeVarargs 74 : public static <V> Schema<V> schema(FieldDef<V, ?>... fields) { 75 0 : return new Schema.Builder<V>().version(0).add(fields).build(); 76 : } 77 : 78 : @SafeVarargs 79 : public static <V> Schema<V> schema(int version, FieldDef<V, ?>... fields) { 80 153 : return new Schema.Builder<V>().version(version).add(fields).build(); 81 : } 82 : 83 : public static <V> Schema<V> schema(int version, ImmutableList<FieldDef<V, ?>> fields) { 84 0 : return new Schema.Builder<V>().version(version).add(fields).build(); 85 : } 86 : 87 : @SafeVarargs 88 : public static <V> Schema<V> schema(Schema<V> schema, FieldDef<V, ?>... moreFields) { 89 154 : return new Schema.Builder<V>().add(schema).add(moreFields).build(); 90 : } 91 : 92 : public static <V> Schema<V> schema( 93 : int version, 94 : ImmutableList<FieldDef<V, ?>> fieldDefs, 95 : ImmutableList<IndexedField<V, ?>> indexedFields, 96 : ImmutableList<IndexedField<V, ?>.SearchSpec> searchSpecs) { 97 154 : return new Schema.Builder<V>() 98 154 : .version(version) 99 154 : .add(fieldDefs) 100 154 : .addIndexedFields(indexedFields) 101 154 : .addSearchSpecs(searchSpecs) 102 154 : .build(); 103 : } 104 : 105 : public static <V> Schema<V> schema( 106 : Schema<V> schema, 107 : ImmutableList<FieldDef<V, ?>> fieldDefs, 108 : ImmutableList<IndexedField<V, ?>> indexedFields, 109 : ImmutableList<IndexedField<V, ?>.SearchSpec> searchSpecs) { 110 0 : return new Schema.Builder<V>() 111 0 : .add(schema) 112 0 : .add(fieldDefs) 113 0 : .addIndexedFields(indexedFields) 114 0 : .addSearchSpecs(searchSpecs) 115 0 : .build(); 116 : } 117 : 118 : public static <V> Schema<V> schema( 119 : ImmutableList<FieldDef<V, ?>> fieldDefs, 120 : ImmutableList<IndexedField<V, ?>> indexFields, 121 : ImmutableList<IndexedField<V, ?>.SearchSpec> searchSpecs) { 122 0 : return schema(/* version= */ 0, fieldDefs, indexFields, searchSpecs); 123 : } 124 : 125 : public static Set<String> getPersonParts(PersonIdent person) { 126 104 : if (person == null) { 127 0 : return ImmutableSet.of(); 128 : } 129 104 : return getNameParts(person.getName(), Collections.singleton(person.getEmailAddress())); 130 : } 131 : 132 : public static Set<String> getNameParts(String name) { 133 14 : return getNameParts(name, Collections.emptySet()); 134 : } 135 : 136 : public static Set<String> getNameParts(String name, Iterable<String> emails) { 137 111 : Splitter at = Splitter.on('@'); 138 111 : Splitter s = Splitter.on(CharMatcher.anyOf("@.- /_")).omitEmptyStrings(); 139 111 : HashSet<String> parts = new HashSet<>(); 140 111 : for (String email : emails) { 141 109 : if (email == null) { 142 35 : continue; 143 : } 144 109 : String lowerEmail = email.toLowerCase(Locale.US); 145 109 : parts.add(lowerEmail); 146 109 : Iterables.addAll(parts, at.split(lowerEmail)); 147 109 : Iterables.addAll(parts, s.split(lowerEmail)); 148 109 : } 149 111 : if (name != null) { 150 111 : Iterables.addAll(parts, s.split(name.toLowerCase(Locale.US))); 151 : } 152 111 : return parts; 153 : } 154 : 155 : private SchemaUtil() {} 156 : }