Home | History | Annotate | Download | only in res
      1 package com.xtremelabs.robolectric.res;
      2 
      3 import org.w3c.dom.Node;
      4 import org.w3c.dom.NodeList;
      5 
      6 import javax.xml.xpath.XPathConstants;
      7 import javax.xml.xpath.XPathExpression;
      8 import javax.xml.xpath.XPathExpressionException;
      9 import javax.xml.xpath.XPathFactory;
     10 import java.util.ArrayList;
     11 import java.util.HashMap;
     12 import java.util.List;
     13 import java.util.Map;
     14 
     15 public class PluralResourceLoader extends XpathResourceXmlLoader implements ResourceValueConverter {
     16     Map<String, PluralRules> plurals = new HashMap<String, PluralRules>();
     17     private StringResourceLoader stringResourceLoader;
     18 
     19     public PluralResourceLoader(ResourceExtractor resourceExtractor, StringResourceLoader stringResourceLoader) {
     20         super(resourceExtractor, "/resources/plurals");
     21         this.stringResourceLoader = stringResourceLoader;
     22     }
     23 
     24     public String getValue(int resourceId, int quantity) {
     25         String name = resourceExtractor.getResourceName(resourceId);
     26         PluralRules rules = plurals.get(name);
     27         if (rules != null) {
     28             Plural p = rules.find(quantity);
     29             if (p != null) {
     30                 return p.string;
     31             }
     32         }
     33         return null;
     34     }
     35 
     36     @Override protected void processNode(Node node, String name, boolean isSystem) throws XPathExpressionException {
     37         XPathExpression itemXPath = XPathFactory.newInstance().newXPath().compile("item");
     38         NodeList childNodes = (NodeList) itemXPath.evaluate(node, XPathConstants.NODESET);
     39         PluralRules rules = new PluralRules();
     40         for (int j = 0; j < childNodes.getLength(); j++) {
     41             Node childNode = childNodes.item(j);
     42             String value = childNode.getTextContent();
     43             String quantity = childNode.getAttributes().getNamedItem("quantity").getTextContent();
     44             if (value.startsWith("@")) {
     45                 value = value.substring(1);
     46                 rules.add(new Plural(quantity, stringResourceLoader.getValue(value, isSystem)));
     47             } else {
     48                 rules.add(new Plural(quantity, value));
     49             }
     50         }
     51         plurals.put("plurals/" + name, rules);
     52     }
     53 
     54     @Override public Object convertRawValue(String rawValue) {
     55         return rawValue;
     56     }
     57 
     58     static class PluralRules {
     59         List<Plural> plurals = new ArrayList<Plural>();
     60 
     61         Plural find(int quantity) {
     62             for (Plural p : plurals) {
     63                 if (p.num == quantity) return p;
     64             }
     65             for (Plural p : plurals) {
     66                 if (p.num == -1) return p;
     67             }
     68             return null;
     69         }
     70 
     71         void add(Plural p) {
     72             plurals.add(p);
     73         }
     74     }
     75 
     76     static class Plural {
     77         final String quantity, string;
     78         final int num;
     79 
     80         Plural(String quantity, String string) {
     81             this.quantity = quantity;
     82             this.string = string;
     83             if ("zero".equals(quantity)) {
     84                 num = 0;
     85             } else if ("one".equals(quantity)) {
     86                 num = 1;
     87             } else if ("two".equals(quantity)) {
     88                 num = 2;
     89             } else if ("other".equals(quantity)) {
     90                 num = -1;
     91             } else {
     92                 num = -1;
     93             }
     94         }
     95     }
     96 }
     97