1 package org.unicode.cldr.util; 2 3 import com.google.common.base.Joiner; 4 import com.ibm.icu.impl.Utility; 5 import com.ibm.icu.text.Transform; 6 import java.util.ArrayList; 7 import java.util.Collections; 8 import java.util.List; 9 import java.util.Set; 10 import java.util.regex.Matcher; 11 import java.util.regex.Pattern; 12 13 /** 14 * Transforms a path by replacing attributes with .* 15 * 16 * @author markdavis 17 */ 18 public class PathStarrer implements Transform<String, String> { 19 public static final String STAR_PATTERN = "([^\"]*+)"; 20 21 private String starredPathString; 22 private final List<String> attributes = new ArrayList<>(); 23 private final List<String> protectedAttributes = Collections.unmodifiableList(attributes); 24 private String substitutionPattern = STAR_PATTERN; 25 26 private static final Pattern ATTRIBUTE_PATTERN_OLD = PatternCache.get("=\"([^\"]*)\""); 27 private final StringBuilder starredPathOld = new StringBuilder(); 28 set(String path)29 public String set(String path) { 30 XPathParts parts = XPathParts.getFrozenInstance(path).cloneAsThawed(); 31 return set(parts, Collections.<String>emptySet()); 32 } 33 34 /** 35 * Sets the path starrer attributes, and returns the string. 36 * 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