1 11 12 package org.eclipse.help.internal.webapp.servlet; 13 14 import java.io.ByteArrayInputStream ; 15 import java.io.ByteArrayOutputStream ; 16 import java.io.FilterOutputStream ; 17 import java.io.IOException ; 18 import java.io.OutputStream ; 19 20 import org.eclipse.help.internal.search.HTMLDocParser; 21 22 27 public class FilterHTMLHeadAndBodyOutputStream extends FilterOutputStream { 28 private static final int STATE_START = 0; 29 30 private static final int STATE_LT = 1; 31 32 private static final int STATE_LT_SLASH = 2; 33 34 private static final int STATE_LT_SLASH_H = 3; 35 36 private static final int STATE_LT_SLASH_HE = 4; 37 38 private static final int STATE_LT_SLASH_HEA = 5; 39 40 private static final int STATE_LT_SLASH_HEAD = 6; 41 42 private static final int STATE_AFTER_HEAD = 7; 43 44 private static final int STATE_LT_B = 8; 45 46 private static final int STATE_LT_BO = 9; 47 48 private static final int STATE_LT_BOD = 10; 49 50 private static final int STATE_LT_BODY = 11; 51 52 private static final int STATE_DONE = 17; 53 54 private static final int STATE_LT_M = 18; 55 private static final int STATE_LT_ME = 19; 56 private static final int STATE_LT_MET = 20; 57 private static final int STATE_LT_META = 21; 58 59 private int areaState = STATE_START; 60 61 private int state = STATE_START; 62 63 private byte[] toHead; 64 65 private String bodyContent; 66 67 private String charset; 68 69 ByteArrayOutputStream buffer = new ByteArrayOutputStream (7); 70 71 86 public FilterHTMLHeadAndBodyOutputStream(OutputStream out, 87 byte[] bytesForHead, String bodyContent) { 88 super(out); 89 toHead = bytesForHead; 90 this.bodyContent = bodyContent; 91 } 92 93 106 public final void write(int b) throws IOException { 107 switch (state) { 108 case STATE_START: 109 case STATE_AFTER_HEAD: 110 if (b == '<') { 111 buffer.write(b); 112 state = STATE_LT; 113 } else { 114 out.write(b); 115 } 116 break; 117 case STATE_LT: 118 buffer.write(b); 119 if (b == '/') { 120 state = STATE_LT_SLASH; 121 } else if (b == 'b' || b == 'B') { 122 state = STATE_LT_B; 123 } else if (b == 'm' || b== 'M') { 124 state = STATE_LT_M; 125 } else { 126 reset(); 127 } 128 break; 129 case STATE_LT_M: 130 buffer.write(b); 131 if (b == 'e' || b=='E') { 132 state = STATE_LT_ME; 133 } 134 else { 135 reset(); 136 } 137 break; 138 case STATE_LT_ME: 139 buffer.write(b); 140 if (b == 't' || b=='T') { 141 state = STATE_LT_MET; 142 } 143 else { 144 reset(); 145 } 146 break; 147 case STATE_LT_MET: 148 buffer.write(b); 149 if (b == 'a' || b=='A') { 150 state = STATE_LT_META; 151 } 152 else { 153 reset(); 154 } 155 break; 156 case STATE_LT_META: 157 buffer.write(b); 158 if (b=='>') { 159 parseMetaTag(buffer); 160 reset(); 161 } 162 break; 163 case STATE_LT_B: 164 buffer.write(b); 165 if (b == 'o' || b == 'O') { 166 state = STATE_LT_BO; 167 } else { 168 reset(); 169 } 170 break; 171 case STATE_LT_BO: 172 buffer.write(b); 173 if (b == 'd' || b == 'D') { 174 state = STATE_LT_BOD; 175 } else { 176 reset(); 177 } 178 break; 179 case STATE_LT_BOD: 180 buffer.write(b); 181 if (b == 'y' || b == 'Y') { 182 state = STATE_LT_BODY; 183 } else { 184 reset(); 185 } 186 break; 187 case STATE_LT_BODY: 188 buffer.write(b); 189 if (b == '>') { 190 out.write(buffer.toByteArray()); 191 buffer.reset(); 192 if (bodyContent != null) { 193 out.write('\n'); 194 byte [] bytes = bodyContent.getBytes(charset!=null?charset:"UTF-8"); out.write(bytes); 196 out.write('\n'); 197 } 198 areaState = STATE_DONE; 199 state = STATE_DONE; 200 } 201 break; 202 case STATE_LT_SLASH: 203 buffer.write(b); 204 if (b == 'h' || b == 'H') { 205 state = STATE_LT_SLASH_H; 206 } else { 207 reset(); 208 } 209 break; 210 case STATE_LT_SLASH_H: 211 buffer.write(b); 212 if (b == 'e' || b == 'E') { 213 state = STATE_LT_SLASH_HE; 214 } else { 215 reset(); 216 } 217 break; 218 case STATE_LT_SLASH_HE: 219 buffer.write(b); 220 if (b == 'a' || b == 'A') { 221 state = STATE_LT_SLASH_HEA; 222 } else { 223 reset(); 224 } 225 break; 226 case STATE_LT_SLASH_HEA: 227 buffer.write(b); 228 if (b == 'd' || b == 'D') { 229 state = STATE_LT_SLASH_HEAD; 230 } else { 231 reset(); 232 } 233 break; 234 case STATE_LT_SLASH_HEAD: 235 buffer.write(b); 236 if (b == '>') { 237 if (toHead != null) { 238 out.write(toHead); 239 out.write('\n'); 240 } 241 areaState = STATE_AFTER_HEAD; 242 state = STATE_AFTER_HEAD; 243 out.write(buffer.toByteArray()); 244 buffer.reset(); 245 } else { 246 reset(); 247 } 248 break; 249 default: out.write(b); 251 break; 252 } 253 } 254 255 private void parseMetaTag(ByteArrayOutputStream buffer) { 256 ByteArrayInputStream is = new ByteArrayInputStream (buffer.toByteArray()); 257 String value = HTMLDocParser.getCharsetFromHTML(is); 258 try { 259 is.close(); 260 } 261 catch (IOException e) { 262 } 263 if (value!=null) 264 this.charset = value; 265 } 266 267 private void reset() throws IOException { 268 out.write(buffer.toByteArray()); 269 buffer.reset(); 270 state = areaState; 271 } 272 273 public void write(byte b[], int off, int len) throws IOException { 274 if (state == STATE_DONE) { 275 out.write(b, off, len); 276 } else { 277 for (int i = 0; i < len; i++) { 278 write(b[off + i]); 279 } 280 } 281 } 282 283 288 public void close() throws IOException { 289 reset(); 290 super.close(); 291 } 292 } 293 | Popular Tags |