• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PluralResourceLoader(ResourceExtractor resourceExtractor, StringResourceLoader stringResourceLoader)19     public PluralResourceLoader(ResourceExtractor resourceExtractor, StringResourceLoader stringResourceLoader) {
20         super(resourceExtractor, "/resources/plurals");
21         this.stringResourceLoader = stringResourceLoader;
22     }
23 
getValue(int resourceId, int quantity)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 
processNode(Node node, String name, boolean isSystem)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 
convertRawValue(String rawValue)54     @Override public Object convertRawValue(String rawValue) {
55         return rawValue;
56     }
57 
58     static class PluralRules {
59         List<Plural> plurals = new ArrayList<Plural>();
60 
find(int quantity)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 
add(Plural p)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 
Plural(String quantity, String string)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