1 32 33 package websphinx; 34 35 import java.io.File ; 36 import java.io.OutputStream ; 37 import java.io.RandomAccessFile ; 38 import java.io.IOException ; 39 import java.io.Writer ; 41 import java.io.OutputStreamWriter ; 42 46 47 public class HTMLTransformer { 48 49 private OutputStream stream; private Writer writer; 56 private boolean openedStream = false; 57 59 private RandomAccessFile readwrite; 61 private HTMLTransformer next; private HTMLTransformer head; private HTMLTransformer tail; 65 private String content; private int emitStart, emitEnd; private int transformEnd; 74 79 public HTMLTransformer (OutputStream out) { 80 head = tail = this; 81 next = null; 82 setOutput (out); 83 } 84 85 91 public HTMLTransformer (String filename) throws IOException { 92 head = tail = this; 93 next = null; 94 openFile (filename, false); 95 } 96 97 98 104 public HTMLTransformer (String filename, boolean seekable) throws IOException { 105 head = tail = this; 106 next = null; 107 openFile (filename, seekable); 108 } 109 110 111 117 public HTMLTransformer (HTMLTransformer next) { 118 this.next = next; 119 tail = next != null ? next.tail : this; 120 for (HTMLTransformer u = this; u != null; u = u.next) 121 u.head = this; 122 } 123 124 private void openFile (String filename, boolean seekable) throws IOException { 125 File file = new File (filename); 126 127 OutputStream out = Access.getAccess ().writeFile (file, false); 129 130 if (!seekable) 131 setOutput (out); 132 else { 133 out.close (); 134 RandomAccessFile raf = Access.getAccess ().readWriteFile (file); 135 setRandomAccessFile (raf); 136 } 137 138 openedStream = true; 139 } 140 141 public void setOutput (OutputStream out) { 143 if (next == null) { 144 stream = out; 145 writer = new OutputStreamWriter (out); 146 } else 147 next.setOutput (out); 148 } 149 150 157 public OutputStream getOutputStream () { 158 return tail.stream; 159 } 160 161 public Writer getOutputWriter () { 162 return tail.writer; 163 } 164 166 178 179 public void setRandomAccessFile (RandomAccessFile raf) { 180 if (next == null) 181 readwrite = raf; 182 else 183 next.setRandomAccessFile (raf); 184 } 185 186 public RandomAccessFile getRandomAccessFile () { 187 return tail.readwrite; 188 } 189 190 195 public synchronized void write (String string) throws IOException { 196 if (next == null) 197 emit (string); 198 else 199 next.write (string); 200 } 201 202 206 public synchronized void write (Region region) throws IOException { 207 if (next == null) { 208 emitPendingRegion (); 209 210 String oldContent = content; 211 int oldEmitStart = emitStart; 212 int oldEmitEnd = emitEnd; 213 int oldTransformEnd = transformEnd; 214 215 content = region.getSource().getContent (); 216 emitStart = emitEnd = region.getStart (); 217 transformEnd = region.getEnd (); 218 219 processElementsInRegion (region.getRootElement(), 220 region.getStart(), 221 region.getEnd()); 222 223 emitPendingRegion (); 224 225 content = oldContent; 226 emitStart = oldEmitStart; 227 emitEnd = oldEmitEnd; 228 transformEnd = oldTransformEnd; 229 } 230 else 231 next.write (region); 232 } 233 234 238 public synchronized void writePage (Page page) throws IOException { 239 if (next == null) { 240 if (page.isHTML ()) 241 write (page); 242 else { 243 System.err.println ("binary write of " + page.getURL ()); 244 writeStream (page.getContentBytes (), 245 0, page.getLength ()); 246 } 247 } 248 else 249 next.writePage (page); 250 } 251 252 256 public synchronized void flush () throws IOException { 257 if (next == null) { 258 emitPendingRegion (); 259 if (stream != null) 260 stream.flush (); 261 if (writer != null) 262 writer.flush (); 263 } 264 else 265 next.flush (); 266 } 267 268 275 public synchronized void close () throws IOException { 276 flush (); 277 if (next == null) { 278 if (openedStream) { 279 if (stream != null) 280 stream.close (); 281 if (readwrite != null) 282 readwrite.close (); 283 } 284 } 285 else 286 next.close (); 287 } 288 289 292 protected void finalize() throws Throwable { 293 close (); 294 } 295 296 301 public long getFilePointer () throws IOException { 302 if (readwrite == null) 303 throw new IOException ("HTMLTransformer not opened for random access"); 304 return readwrite.getFilePointer (); 305 } 306 307 312 public void seek (long pos) throws IOException { 313 if (readwrite == null) 314 throw new IOException ("HTMLTransformer not opened for random access"); 315 readwrite.seek (pos); 316 } 317 318 323 protected void transformElement (Element elem) throws IOException { 324 head.handleElement (elem); 325 } 326 327 333 protected void transformContents (Element elem) throws IOException { 334 Tag startTag = elem.getStartTag (); 335 Tag endTag = elem.getEndTag (); 336 337 tail.processElementsInRegion (elem.getChild(), 338 startTag.getEnd(), 339 endTag != null ? endTag.getStart() : elem.getEnd()); 340 } 341 342 348 protected void handleElement (Element elem) throws IOException { 349 if (next == null) { 350 Tag startTag = elem.getStartTag (); 351 Tag endTag = elem.getEndTag (); 352 353 emit (startTag); 354 transformContents (elem); 355 if (endTag != null) 356 emit (endTag); 357 } 358 else 359 next.handleElement (elem); 360 } 361 362 367 protected void emit (Region r) throws IOException { 368 tail.emitInternal (r.getSource().getContent(), r.getStart(), r.getEnd ()); 369 } 370 371 375 protected void emit (String string) throws IOException { 376 tail.emitInternal (string, 0, string.length()); 377 } 378 379 private void processElementsInRegion (Element elem, int start, int end) throws IOException { 380 if (this != tail) 381 throw new RuntimeException ("processElementsInRegion not called on tail"); 382 383 int p = start; 384 385 if (elem != null && elem.getSource().getContent() == content) 386 end = Math.min (end, transformEnd); 387 388 while (elem != null && elem.getStartTag().getEnd() <= end) { 389 emitInternal (content, p, elem.getStart()); 390 transformElement (elem); 391 p = elem.getEnd (); 392 elem = elem.getNext (); 393 } 394 emitInternal (content, Math.min (p, end), end); 395 } 396 397 private void emitInternal (String str, int start, int end) throws IOException { 398 if (this != tail) 399 throw new RuntimeException ("emitInternal not called on tail"); 400 401 if (str == content) { 402 start = Math.min (start, transformEnd); 403 end = Math.min (end, transformEnd); 404 405 if (start == emitEnd) 406 emitEnd = end; else { 408 emitPendingRegion (); 409 emitStart = start; 410 emitEnd = end; 411 } 412 } 413 else { 414 emitPendingRegion (); 415 writeStream (str.substring (start, end)); 416 } 417 } 418 419 private void emitPendingRegion () throws IOException { 420 if (this != tail) 421 throw new RuntimeException ("emitPendingRegion not called on tail"); 422 423 if (emitStart != emitEnd) { 424 writeStream (content.substring (emitStart, emitEnd)); 425 emitStart = emitEnd; 426 } 427 } 428 429 private void writeStream (String s) throws IOException { 430 if (writer != null) { 431 writer.write (s); 433 437 } 438 else 439 readwrite.writeBytes (s); 440 } 441 442 private void writeStream (byte[] buf, int offset, int len) throws IOException { 443 if (stream != null) { 444 stream.write (buf, offset, len); 446 450 } 451 else 452 readwrite.write (buf, offset, len); 453 } 454 455 473 } 474 475 489 | Popular Tags |