All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robolectric.res.ResBundle Maven / Gradle / Ivy

There is a newer version: 4.13
Show newest version
package org.robolectric.res;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

public class ResBundle {
  private final ResMap valuesMap = new ResMap();

  public void put(ResName resName, TypedResource value) {
    valuesMap.put(resName, value);
  }

  public TypedResource get(ResName resName, String qualifiers) {
    return valuesMap.pick(resName, qualifiers);
  }

  public void receive(ResourceTable.Visitor visitor) {
    for (final Map.Entry> entry : valuesMap.map.entrySet()) {
      visitor.visit(entry.getKey(), entry.getValue().values());
    }
  }

  static class ResMap {
    private final Map> map = new HashMap<>();

    public TypedResource pick(ResName resName, String qualifiersStr) {
      Map values = map.get(resName);
      if (values == null || values.size() == 0) return null;

      TreeSet typedResources = new TreeSet<>(new QualifierSort());
      typedResources.addAll(values.values());

      // This should really follow the android algorithm specified at:
      // http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch
      //
      // 1: eliminate resources that contradict the qualifiersStr
      // 2: pick the (next) highest-precedence qualifier type in "table 2" of the reference above
      // 3: check if any resource values use this qualifier, if no, back to 2, else move on to 4.
      // 4: eliminate resources values that don't use this qualifier.
      // 5: if more than one resource is left, go back to 2.
      //
      // However, we currently only model the smallest/available width/height and version qualifiers
      // rather than all of the possibly qualifier classes in table 2.

      Qualifiers toMatch = Qualifiers.parse(qualifiersStr);

      List passesRequirements = new ArrayList<>();
      for (TypedResource candidate : typedResources) {
        Qualifiers qualifiers = Qualifiers.parse(candidate.getQualifiers());
        if (qualifiers.passesRequirements(toMatch)) {
          passesRequirements.add(candidate);
        }
      }

      Qualifiers bestMatchQualifiers = null;
      TypedResource bestMatch = null;
      for (TypedResource candidate : passesRequirements) {
        Qualifiers qualifiers = Qualifiers.parse(candidate.getQualifiers());
        if (qualifiers.matches(toMatch)) {
          if (bestMatchQualifiers == null || qualifiers.isBetterThan(bestMatchQualifiers, toMatch)) {
            bestMatchQualifiers = qualifiers;
            bestMatch =  candidate;
          }
        }
      }
      if (bestMatch != null) {
        return bestMatch;
      }
      if (!passesRequirements.isEmpty()) {
        return passesRequirements.get(0);
      }
      return null;
    }

    public void put(ResName resName, TypedResource value) {
      Map values = map.get(resName);
      if (values == null) map.put(resName, values = new HashMap<>());
      if (!values.containsKey(value.getQualifiers())) {
        values.put(value.getQualifiers(), value);
      }
    }

    public int size() {
      return map.size();
    }

    public static class QualifierSort implements Comparator {
      @Override
      public int compare(TypedResource o1, TypedResource o2) {
        return o1.getQualifiers().compareTo(o2.getQualifiers());
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy