You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.0 KiB
170 lines
6.0 KiB
package com.google.android.libraries.backup;
|
|
|
|
import android.content.Context;
|
|
import java.lang.annotation.Annotation;
|
|
import java.lang.reflect.Field;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
/** Static utility methods returning {@link BackupKeyPredicate} instances. */
|
|
public class BackupKeyPredicates {
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key was defined as a field with the given
|
|
* annotation in one of the given classes. Assumes that the given annotation and classes are
|
|
* valid. You must ensure that proguard does not remove your annotation or any fields annotated
|
|
* with it.
|
|
*
|
|
* @see Backup
|
|
*/
|
|
public static BackupKeyPredicate buildPredicateFromAnnotatedFieldsIn(
|
|
Class<? extends Annotation> annotation, Class<?>... klasses) {
|
|
return in(getAnnotatedFieldValues(annotation, klasses));
|
|
}
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key matches a regex that was defined as a field
|
|
* with the given annotation in one of the given classes. The test used is equivalent to
|
|
* {@link #containsPattern(String)} for each annotated field value. Assumes that the given
|
|
* annotation and classes are valid. You must ensure that proguard does not remove your annotation
|
|
* or any fields annotated with it.
|
|
*
|
|
* @see Backup
|
|
*/
|
|
public static BackupKeyPredicate buildPredicateFromAnnotatedRegexFieldsIn(
|
|
Class<? extends Annotation> annotation, Class<?>... klasses) {
|
|
Set<String> patterns = getAnnotatedFieldValues(annotation, klasses);
|
|
Set<BackupKeyPredicate> patternPredicates = new HashSet<>();
|
|
for (String pattern : patterns) {
|
|
patternPredicates.add(containsPattern(pattern));
|
|
}
|
|
return or(patternPredicates);
|
|
}
|
|
|
|
private static Set<String> getAnnotatedFieldValues(
|
|
Class<? extends Annotation> annotation, Class<?>... klasses) {
|
|
Set<String> values = new HashSet<>();
|
|
for (Class<?> klass : klasses) {
|
|
addAnnotatedFieldValues(annotation, klass, values);
|
|
}
|
|
return values;
|
|
}
|
|
|
|
private static void addAnnotatedFieldValues(
|
|
Class<? extends Annotation> annotation, Class<?> klass, Set<String> values) {
|
|
for (Field field : klass.getDeclaredFields()) {
|
|
addFieldValueIfAnnotated(annotation, field, values);
|
|
}
|
|
}
|
|
|
|
private static void addFieldValueIfAnnotated(
|
|
Class<? extends Annotation> annotation, Field field, Set<String> values) {
|
|
if (field.isAnnotationPresent(annotation) && field.getType().equals(String.class)) {
|
|
try {
|
|
values.add((String) field.get(null));
|
|
} catch (IllegalAccessException e) {
|
|
throw new IllegalArgumentException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key is a member of the given collection. Changes
|
|
* to the given collection will change the returned predicate.
|
|
*/
|
|
public static BackupKeyPredicate in(final Collection<? extends String> collection) {
|
|
if (collection == null) {
|
|
throw new NullPointerException("Null collection given.");
|
|
}
|
|
return new BackupKeyPredicate() {
|
|
@Override
|
|
public boolean shouldBeBackedUp(String key) {
|
|
return collection.contains(key);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key contains any match for the given regular
|
|
* expression pattern. The test used is equivalent to {@link Matcher#find()}.
|
|
*/
|
|
public static BackupKeyPredicate containsPattern(String pattern) {
|
|
final Pattern compiledPattern = Pattern.compile(pattern);
|
|
return new BackupKeyPredicate() {
|
|
@Override
|
|
public boolean shouldBeBackedUp(String key) {
|
|
return compiledPattern.matcher(key).find();
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key passes any of the given predicates. Each
|
|
* predicate is evaluated in the order given, and the evaluation process stops as soon as an
|
|
* accepting predicate is found. Changes to the given iterable will not change the returned
|
|
* predicate. The returned predicate returns {@code false} for any key if the given iterable is
|
|
* empty.
|
|
*/
|
|
public static BackupKeyPredicate or(Iterable<BackupKeyPredicate> predicates) {
|
|
final List<BackupKeyPredicate> copiedPredicates = new ArrayList<>();
|
|
for (BackupKeyPredicate predicate : predicates) {
|
|
copiedPredicates.add(predicate);
|
|
}
|
|
return orDefensivelyCopied(new ArrayList<>(copiedPredicates));
|
|
}
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key passes any of the given predicates. Each
|
|
* predicate is evaluated in the order given, and the evaluation process stops as soon as an
|
|
* accepting predicate is found. The returned predicate returns {@code false} for any key if no
|
|
* there are no given predicates.
|
|
*/
|
|
public static BackupKeyPredicate or(BackupKeyPredicate... predicates) {
|
|
return orDefensivelyCopied(Arrays.asList(predicates));
|
|
}
|
|
|
|
private static BackupKeyPredicate orDefensivelyCopied(
|
|
final Iterable<BackupKeyPredicate> predicates) {
|
|
return new BackupKeyPredicate() {
|
|
@Override
|
|
public boolean shouldBeBackedUp(String key) {
|
|
for (BackupKeyPredicate predicate : predicates) {
|
|
if (predicate.shouldBeBackedUp(key)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Returns a predicate that determines whether a key is one of the resources from the provided
|
|
* resource IDs. Assumes that all of the given resource IDs are valid.
|
|
*/
|
|
public static BackupKeyPredicate buildPredicateFromResourceIds(
|
|
Context context, Collection<Integer> ids) {
|
|
Set<String> keys = new HashSet<>();
|
|
for (Integer id : ids) {
|
|
keys.add(context.getString(id));
|
|
}
|
|
return in(keys);
|
|
}
|
|
|
|
/** Returns a predicate that returns true for any key. */
|
|
public static BackupKeyPredicate alwaysTrue() {
|
|
return new BackupKeyPredicate() {
|
|
@Override
|
|
public boolean shouldBeBackedUp(String key) {
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
}
|