1 27 28 package nextapp.echo2.webrender.util; 29 30 34 public class JavaScriptCompressor { 35 36 private static final char LINE_FEED = '\n'; 37 private static final char CARRIAGE_RETURN = '\r'; 38 private static final char SPACE = ' '; 39 private static final char TAB = '\t'; 40 41 48 public static String compress(String script) { 49 JavaScriptCompressor jsc = new JavaScriptCompressor(script); 50 return jsc.outputBuffer.toString(); 51 } 52 53 54 private String script; 55 56 61 private StringBuffer outputBuffer; 62 63 64 private int pos; 65 66 67 private char ch; 68 69 70 private char lastAppend; 71 72 73 private boolean endReached; 74 75 76 private boolean contentAppendedAfterLastIdentifier = true; 77 78 83 private JavaScriptCompressor(String script) { 84 this.script = script; 85 outputBuffer = new StringBuffer (script.length()); 86 nextChar(); 87 88 while (!endReached) { 89 if (Character.isJavaIdentifierStart(ch)) { 90 renderIdentifier(); 91 } else if (ch == ' ') { 92 skipWhiteSpace(); 93 } else if (isWhitespace()) { 94 skipWhiteSpace(); 96 } else if ((ch == '"') || (ch == '\'')) { 97 renderString(); 99 } else if (ch == '/') { 100 nextChar(); 102 if (ch == '/') { 103 nextChar(); 104 skipLineComment(); 105 } else if (ch == '*') { 106 nextChar(); 107 skipBlockComment(); 108 } else { 109 append('/'); 110 } 111 } else { 112 append(ch); 113 nextChar(); 114 } 115 } 116 } 117 118 123 private void append(char ch) { 124 lastAppend = ch; 125 outputBuffer.append(ch); 126 contentAppendedAfterLastIdentifier = true; 127 } 128 129 134 private boolean isWhitespace() { 135 return ch == CARRIAGE_RETURN || ch == SPACE || ch == TAB || ch == LINE_FEED; 136 } 137 138 141 private void nextChar() { 142 if (!endReached) { 143 if (pos < script.length()) { 144 ch = script.charAt(pos++); 145 } else { 146 endReached = true; 147 ch = 0; 148 } 149 } 150 } 151 152 155 private void renderIdentifier() { 156 if (!contentAppendedAfterLastIdentifier) 157 append(SPACE); 158 append(ch); 159 nextChar(); 160 while (Character.isJavaIdentifierPart(ch)) { 161 append(ch); 162 nextChar(); 163 } 164 contentAppendedAfterLastIdentifier = false; 165 } 166 167 170 private void renderString() { 171 char startCh = ch; append(ch); 173 nextChar(); 174 while (true) { 175 if ((ch == LINE_FEED) || (ch == CARRIAGE_RETURN) || (endReached)) { 176 return; 178 } else { 179 if (ch == '\\') { 180 append(ch); 181 nextChar(); 182 if ((ch == LINE_FEED) || (ch == CARRIAGE_RETURN) || (endReached)) { 183 return; 185 } 186 append(ch); 187 nextChar(); 188 } else { 189 append(ch); 190 if (ch == startCh) { 191 nextChar(); 192 return; 193 } 194 nextChar(); 195 } 196 } 197 } 198 } 199 200 203 private void skipLineComment() { 204 while ((ch != CARRIAGE_RETURN) && (ch != LINE_FEED)) { 205 if (endReached) { 206 return; 207 } 208 nextChar(); 209 } 210 } 211 212 215 private void skipBlockComment() { 216 while (true) { 217 if (endReached) { 218 return; 219 } 220 if (ch == '*') { 221 nextChar(); 222 if (ch == '/') { 223 nextChar(); 224 return; 225 } 226 } else 227 nextChar(); 228 } 229 } 230 231 235 private void renderNewLine() { 236 if (lastAppend != '\n' && lastAppend != '\r') { 237 append('\n'); 238 } 239 } 240 241 244 private void skipWhiteSpace() { 245 if (ch == LINE_FEED || ch == CARRIAGE_RETURN) { 246 renderNewLine(); 247 } else { 248 append(ch); 249 } 250 nextChar(); 251 while (ch == LINE_FEED || ch == CARRIAGE_RETURN || ch == SPACE || ch == TAB) { 252 if (ch == LINE_FEED || ch == CARRIAGE_RETURN) { 253 renderNewLine(); 254 } 255 nextChar(); 256 } 257 } 258 } 259 | Popular Tags |