blob: 959002ad14f8079680bae6f2c2a135a27e3b0d9a [file] [log] [blame]
/*
* Copyright (C) 2018 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.android.ide.common.resources;
import com.android.annotations.NonNull;
import com.android.ide.common.rendering.api.ResourceNamespace;
import com.android.resources.ResourceType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
/**
* Base class for resource repository classes. Provides implementations of resource lookup methods.
*/
public abstract class AbstractResourceRepository implements ResourceRepository {
/**
* Returns the {@link ListMultimap} containing resources with the given namespace and type keyed
* by resource names. Unlike {@link #getResources(ResourceNamespace, ResourceType)}, this method
* is expected to return the map directly backed by the internal resource storage, although
* the returned map doesn't have to be mutable.
*
* @param namespace the namespace of the resources to return
* @param resourceType the type of the resources to return
* @return the resources matching the namespace and type
*/
@NonNull
protected abstract ListMultimap<String, ResourceItem> getResourcesInternal(
@NonNull ResourceNamespace namespace, @NonNull ResourceType resourceType);
@Override
@NonNull
public List<ResourceItem> getResources(
@NonNull ResourceNamespace namespace,
@NonNull ResourceType resourceType,
@NonNull String resourceName) {
ListMultimap<String, ResourceItem> map = getResourcesInternal(namespace, resourceType);
List<ResourceItem> items = map.get(resourceName);
return items.isEmpty() ? ImmutableList.of() : ImmutableList.copyOf(items);
}
@Override
@NonNull
public List<ResourceItem> getResources(
@NonNull ResourceNamespace namespace,
@NonNull ResourceType resourceType,
@NonNull Predicate<ResourceItem> filter) {
List<ResourceItem> result = null;
ListMultimap<String, ResourceItem> map = getResourcesInternal(namespace, resourceType);
for (ResourceItem item : map.values()) {
if (filter.test(item)) {
if (result == null) {
result = new ArrayList<>();
}
result.add(item);
}
}
return result == null ? ImmutableList.of() : result;
}
@Override
@NonNull
public ListMultimap<String, ResourceItem> getResources(
@NonNull ResourceNamespace namespace, @NonNull ResourceType resourceType) {
ListMultimap<String, ResourceItem> map = getResourcesInternal(namespace, resourceType);
return ImmutableListMultimap.copyOf(map);
}
@Override
public boolean hasResources(
@NonNull ResourceNamespace namespace,
@NonNull ResourceType resourceType,
@NonNull String resourceName) {
ListMultimap<String, ResourceItem> map = getResourcesInternal(namespace, resourceType);
List<ResourceItem> items = map.get(resourceName);
return !items.isEmpty();
}
@Override
public boolean hasResources(
@NonNull ResourceNamespace namespace, @NonNull ResourceType resourceType) {
ListMultimap<String, ResourceItem> map = getResourcesInternal(namespace, resourceType);
return !map.isEmpty();
}
@Override
@NonNull
public Set<ResourceType> getResourceTypes(@NonNull ResourceNamespace namespace) {
EnumSet<ResourceType> result = EnumSet.noneOf(ResourceType.class);
for (ResourceType resourceType : ResourceType.values()) {
if (hasResources(namespace, resourceType)) {
result.add(resourceType);
}
}
return Sets.immutableEnumSet(result);
}
/**
* Helper method to be used by implementations of the {@link #accept(ResourceVisitor)} method.
*/
protected static ResourceVisitor.VisitResult acceptByResources(
@NonNull Map<ResourceType, ListMultimap<String, ResourceItem>> map,
@NonNull ResourceVisitor visitor) {
for (Map.Entry<ResourceType, ListMultimap<String, ResourceItem>> entry : map.entrySet()) {
if (visitor.shouldVisitResourceType(entry.getKey())) {
for (ResourceItem item : entry.getValue().values()) {
if (visitor.visit(item) == ResourceVisitor.VisitResult.ABORT) {
return ResourceVisitor.VisitResult.ABORT;
}
}
}
}
return ResourceVisitor.VisitResult.CONTINUE;
}
}