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