1 package net.sf.saxon.event; 2 import net.sf.saxon.om.XMLChar; 3 import net.sf.saxon.om.FastStringBuffer; 4 import net.sf.saxon.trans.XPathException; 5 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.List ; 9 10 16 17 18 public class CharacterMapExpander extends ProxyReceiver { 19 20 private HashMap charMap; 21 private int min = Integer.MAX_VALUE; private int max = 0; private boolean useNullMarkers = true; 24 25 29 30 public void setCharacterMaps(List maps) { 31 36 charMap = new HashMap (64); 37 for (int i = 0; i < maps.size(); i++) { 38 HashMap hashMap = (HashMap )maps.get(i); 39 Iterator keys = hashMap.keySet().iterator(); 40 while (keys.hasNext()) { 41 Integer next = (Integer )keys.next(); 42 int n = next.intValue(); 43 if (n < min) { 44 min = n; 45 } 46 if (n > max) { 47 max = n; 48 } 49 charMap.put(next, hashMap.get(next)); 50 } 51 } 52 if (min > 0xD800) { 53 min = 0xD800; 56 } 57 } 58 59 63 64 public void setUseNullMarkers(boolean use) { 65 useNullMarkers = use; 66 } 67 68 71 72 public void attribute(int nameCode, int typeCode, CharSequence value, int locationId, int properties) 73 throws XPathException { 74 if ((properties & ReceiverOptions.DISABLE_CHARACTER_MAPS) == 0) { 75 CharSequence mapped = map(value, useNullMarkers); 76 if (mapped == value) { 77 super.attribute(nameCode, typeCode, value, locationId, properties); 79 } else { 80 super.attribute(nameCode, typeCode, mapped, 81 locationId, properties | ReceiverOptions.USE_NULL_MARKERS); 82 } 83 } else { 84 super.attribute(nameCode, typeCode, value, locationId, properties); 85 } 86 } 87 88 91 92 public void characters(CharSequence chars, int locationId, int properties) throws XPathException { 93 94 if ((properties & ReceiverOptions.DISABLE_ESCAPING) == 0) { 95 super.characters(map(chars, useNullMarkers), locationId, 96 (properties | ReceiverOptions.USE_NULL_MARKERS) & ~ReceiverOptions.NO_SPECIAL_CHARS); 97 } else { 98 super.characters(chars, locationId, properties); 101 } 102 103 } 104 105 112 113 private CharSequence map(CharSequence in, boolean insertNulls) { 114 115 118 boolean move = false; 119 for (int i=0; i<in.length();) { 120 char c = in.charAt(i++); 121 if (c >= min && c <= max) { 122 move = true; 123 break; 124 } 125 } 126 if (!move) { 127 return in; 128 } 129 130 FastStringBuffer buffer = new FastStringBuffer(in.length()*2); 131 int i = 0; 132 while(i < in.length()) { 133 char c = in.charAt(i++); 134 if (c >= min && c <= max) { 135 if (XMLChar.isHighSurrogate(c)) { 136 char d = in.charAt(i++); 138 int s = XMLChar.supplemental(c, d); 139 String rep = (String )charMap.get(new Integer (s)); 140 if (rep == null) { 141 buffer.append(c); 142 buffer.append(d); 143 } else { 144 if (insertNulls) { 145 buffer.append((char)0); 146 buffer.append(rep); 147 buffer.append((char)0); 148 } else { 149 buffer.append(rep); 150 } 151 } 152 } else { 153 String rep = (String )charMap.get(new Integer (c)); 154 if (rep == null) { 155 buffer.append(c); 156 } else { 157 if (insertNulls) { 158 buffer.append((char)0); 159 buffer.append(rep); 160 buffer.append((char)0); 161 } else { 162 buffer.append(rep); 163 } 164 } 165 } 166 } else { 167 buffer.append(c); 168 } 169 } 170 return buffer; 171 } 172 173 174 }; 175 176 194 | Popular Tags |