1 package org.unicode.cldr.util; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.List; 6 import java.util.Set; 7 import java.util.regex.Matcher; 8 import java.util.regex.Pattern; 9 10 import com.google.common.base.Joiner; 11 import com.ibm.icu.impl.Utility; 12 import com.ibm.icu.text.Transform; 13 14 /** 15 * Transforms a path by replacing attributes with .* 16 * 17 * @author markdavis 18 */ 19 public class PathStarrer implements Transform<String, String> { 20 public static final String STAR_PATTERN = "([^\"]*+)"; 21 22 private String starredPathString; 23 private final List<String> attributes = new ArrayList<>(); 24 private final List<String> protectedAttributes = Collections.unmodifiableList(attributes); 25 private String substitutionPattern = STAR_PATTERN; 26 27 private static final Pattern ATTRIBUTE_PATTERN_OLD = PatternCache.get("=\"([^\"]*)\""); 28 private final StringBuilder starredPathOld = new StringBuilder(); 29 set(String path)30 public String set(String path) { 31 XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); 32 return set(parts, Collections.<String> emptySet()); 33 } 34 35 /** 36 * Sets the path starrer attributes, and returns the string. 37 * @param parts 38 * @return 39 */ set(XPathParts parts, Set<String> skipAttributes)40 public String set(XPathParts parts, Set<String> skipAttributes) { 41 attributes.clear(); 42 for (int i = 0; i < parts.size(); ++i) { 43 for (String key : parts.getAttributeKeys(i)) { 44 if (!skipAttributes.contains(key)) { 45 attributes.add(parts.getAttributeValue(i, key)); 46 parts.setAttribute(i, key, substitutionPattern); 47 } 48 } 49 } 50 starredPathString = parts.toString(); 51 return starredPathString; 52 } 53 setOld(String path)54 public String setOld(String path) { 55 Matcher starAttributeMatcher = ATTRIBUTE_PATTERN_OLD.matcher(path); 56 starredPathOld.setLength(0); 57 attributes.clear(); 58 int lastEnd = 0; 59 while (starAttributeMatcher.find()) { 60 int start = starAttributeMatcher.start(1); 61 int end = starAttributeMatcher.end(1); 62 starredPathOld.append(path.substring(lastEnd, start)); 63 starredPathOld.append(substitutionPattern); 64 65 attributes.add(path.substring(start, end)); 66 lastEnd = end; 67 } 68 starredPathOld.append(path.substring(lastEnd)); 69 starredPathString = starredPathOld.toString(); 70 return starredPathString; 71 } 72 getAttributes()73 public List<String> getAttributes() { 74 return protectedAttributes; 75 } 76 getAttributesString(String separator)77 public String getAttributesString(String separator) { 78 return Joiner.on(separator).join(attributes); 79 } 80 getResult()81 public String getResult() { 82 return starredPathString; 83 } 84 getSubstitutionPattern()85 public String getSubstitutionPattern() { 86 return substitutionPattern; 87 } 88 setSubstitutionPattern(String substitutionPattern)89 public PathStarrer setSubstitutionPattern(String substitutionPattern) { 90 this.substitutionPattern = substitutionPattern; 91 return this; 92 } 93 94 @Override transform(String source)95 public String transform(String source) { 96 return set(source); 97 } 98 99 // Used for coverage lookups - strips off the leading ^ and trailing $ from regexp pattern. transform2(String source)100 public String transform2(String source) { 101 String result = Utility.unescape(setOld(source)); 102 if (result.startsWith("^") && result.endsWith("$")) { 103 result = result.substring(1, result.length() - 1); 104 } 105 //System.out.println("Path in => "+source); 106 //System.out.println("Path out => "+result); 107 //System.out.println("-----------"); 108 109 return result; 110 } 111 } 112