PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-1-pre5/org/gjt/sp/jedit/buffer/BufferIORequest.java

#
Java | 863 lines | 606 code | 106 blank | 151 comment | 100 complexity | 7c395363375ed842ad886d4d3631343d MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * BufferIORequest.java - I/O request
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2001 Slava Pestov
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.buffer;
  23. //{{{ Imports
  24. import javax.swing.text.Segment;
  25. import java.io.*;
  26. import java.util.zip.*;
  27. import java.util.Vector;
  28. import org.gjt.sp.jedit.io.*;
  29. import org.gjt.sp.jedit.*;
  30. import org.gjt.sp.util.*;
  31. //}}}
  32. /**
  33. * A buffer I/O request.
  34. * @author Slava Pestov
  35. * @version $Id: BufferIORequest.java 4316 2002-08-20 19:11:47Z spestov $
  36. */
  37. public class BufferIORequest extends WorkRequest
  38. {
  39. //{{{ Constants
  40. /**
  41. * Size of I/O buffers.
  42. */
  43. public static final int IOBUFSIZE = 32768;
  44. /**
  45. * Number of lines per progress increment.
  46. */
  47. public static final int PROGRESS_INTERVAL = 300;
  48. public static final String LOAD_DATA = "BufferIORequest__loadData";
  49. public static final String END_OFFSETS = "BufferIORequest__endOffsets";
  50. public static final String NEW_PATH = "BufferIORequest__newPath";
  51. /**
  52. * Buffer boolean property set when an error occurs.
  53. */
  54. public static final String ERROR_OCCURRED = "BufferIORequest__error";
  55. /**
  56. * A file load request.
  57. */
  58. public static final int LOAD = 0;
  59. /**
  60. * A file save request.
  61. */
  62. public static final int SAVE = 1;
  63. /**
  64. * An autosave request. Only supported for local files.
  65. */
  66. public static final int AUTOSAVE = 2;
  67. /**
  68. * An insert file request.
  69. */
  70. public static final int INSERT = 3;
  71. /**
  72. * Magic number used for auto-detecting Unicode and GZIP files.
  73. */
  74. public static final int GZIP_MAGIC_1 = 0x1f;
  75. public static final int GZIP_MAGIC_2 = 0x8b;
  76. public static final int UNICODE_MAGIC_1 = 0xfe;
  77. public static final int UNICODE_MAGIC_2 = 0xff;
  78. //}}}
  79. //{{{ BufferIORequest constructor
  80. /**
  81. * Creates a new buffer I/O request.
  82. * @param type The request type
  83. * @param view The view
  84. * @param buffer The buffer
  85. * @param session The VFS session
  86. * @param vfs The VFS
  87. * @param path The path
  88. */
  89. public BufferIORequest(int type, View view, Buffer buffer,
  90. Object session, VFS vfs, String path)
  91. {
  92. this.type = type;
  93. this.view = view;
  94. this.buffer = buffer;
  95. this.session = session;
  96. this.vfs = vfs;
  97. this.path = path;
  98. markersPath = vfs.getParentOfPath(path)
  99. + '.' + vfs.getFileName(path)
  100. + ".marks";
  101. } //}}}
  102. //{{{ run() method
  103. public void run()
  104. {
  105. switch(type)
  106. {
  107. case LOAD:
  108. load();
  109. break;
  110. case SAVE:
  111. save();
  112. break;
  113. case AUTOSAVE:
  114. autosave();
  115. break;
  116. case INSERT:
  117. insert();
  118. break;
  119. }
  120. } //}}}
  121. //{{{ toString() method
  122. public String toString()
  123. {
  124. String typeString;
  125. switch(type)
  126. {
  127. case LOAD:
  128. typeString = "LOAD";
  129. break;
  130. case SAVE:
  131. typeString = "SAVE";
  132. break;
  133. case AUTOSAVE:
  134. typeString = "AUTOSAVE";
  135. break;
  136. default:
  137. typeString = "UNKNOWN!!!";
  138. }
  139. return getClass().getName() + "[type=" + typeString
  140. + ",buffer=" + buffer + "]";
  141. } //}}}
  142. //{{{ Private members
  143. //{{{ Instance variables
  144. private int type;
  145. private View view;
  146. private Buffer buffer;
  147. private Object session;
  148. private VFS vfs;
  149. private String path;
  150. private String markersPath;
  151. //}}}
  152. //{{{ load() method
  153. private void load()
  154. {
  155. InputStream in = null;
  156. try
  157. {
  158. try
  159. {
  160. String[] args = { vfs.getFileName(path) };
  161. setAbortable(true);
  162. if(!buffer.isTemporary())
  163. {
  164. setStatus(jEdit.getProperty("vfs.status.load",args));
  165. setProgressValue(0);
  166. }
  167. path = vfs._canonPath(session,path,view);
  168. VFS.DirectoryEntry entry = vfs._getDirectoryEntry(
  169. session,path,view);
  170. long length;
  171. if(entry != null)
  172. length = entry.length;
  173. else
  174. length = 0L;
  175. in = vfs._createInputStream(session,path,false,view);
  176. if(in == null)
  177. return;
  178. in = new BufferedInputStream(in);
  179. if(in.markSupported())
  180. {
  181. in.mark(2);
  182. int b1 = in.read();
  183. int b2 = in.read();
  184. in.reset();
  185. if(b1 == GZIP_MAGIC_1 && b2 == GZIP_MAGIC_2)
  186. {
  187. in = new GZIPInputStream(in);
  188. buffer.setBooleanProperty(Buffer.GZIPPED,true);
  189. }
  190. else if((b1 == UNICODE_MAGIC_1 && b2 == UNICODE_MAGIC_2)
  191. || (b1 == UNICODE_MAGIC_2 && b2 == UNICODE_MAGIC_1))
  192. {
  193. buffer.setProperty(Buffer.ENCODING,"Unicode");
  194. }
  195. }
  196. else if(path.toLowerCase().endsWith(".gz"))
  197. in = new GZIPInputStream(in);
  198. read(buffer,in,length);
  199. buffer.setNewFile(false);
  200. }
  201. catch(CharConversionException ch)
  202. {
  203. Log.log(Log.ERROR,this,ch);
  204. Object[] pp = { buffer.getProperty(Buffer.ENCODING),
  205. ch.toString() };
  206. VFSManager.error(view,path,"ioerror.encoding-error",pp);
  207. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  208. }
  209. catch(UnsupportedEncodingException uu)
  210. {
  211. Log.log(Log.ERROR,this,uu);
  212. Object[] pp = { buffer.getProperty(Buffer.ENCODING),
  213. uu.toString() };
  214. VFSManager.error(view,path,"ioerror.encoding-error",pp);
  215. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  216. }
  217. catch(IOException io)
  218. {
  219. Log.log(Log.ERROR,this,io);
  220. Object[] pp = { io.toString() };
  221. VFSManager.error(view,path,"ioerror.read-error",pp);
  222. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  223. }
  224. catch(OutOfMemoryError oom)
  225. {
  226. Log.log(Log.ERROR,this,oom);
  227. VFSManager.error(view,path,"out-of-memory-error",null);
  228. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  229. }
  230. if(jEdit.getBooleanProperty("persistentMarkers"))
  231. {
  232. try
  233. {
  234. String[] args = { vfs.getFileName(path) };
  235. if(!buffer.isTemporary())
  236. setStatus(jEdit.getProperty("vfs.status.load-markers",args));
  237. setAbortable(true);
  238. in = vfs._createInputStream(session,markersPath,true,view);
  239. if(in != null)
  240. readMarkers(buffer,in);
  241. }
  242. catch(IOException io)
  243. {
  244. // ignore
  245. }
  246. }
  247. }
  248. catch(WorkThread.Abort a)
  249. {
  250. if(in != null)
  251. {
  252. try
  253. {
  254. in.close();
  255. }
  256. catch(IOException io)
  257. {
  258. }
  259. }
  260. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  261. }
  262. finally
  263. {
  264. try
  265. {
  266. vfs._endVFSSession(session,view);
  267. }
  268. catch(IOException io)
  269. {
  270. Log.log(Log.ERROR,this,io);
  271. String[] pp = { io.toString() };
  272. VFSManager.error(view,path,"ioerror.read-error",pp);
  273. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  274. }
  275. catch(WorkThread.Abort a)
  276. {
  277. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  278. }
  279. }
  280. } //}}}
  281. //{{{ read() method
  282. private void read(Buffer buffer, InputStream _in, long length)
  283. throws IOException
  284. {
  285. IntegerArray endOffsets = new IntegerArray();
  286. // only true if the file size is known
  287. boolean trackProgress = (!buffer.isTemporary() && length != 0);
  288. if(trackProgress)
  289. {
  290. setProgressValue(0);
  291. setProgressMaximum((int)length);
  292. }
  293. // if the file size is not known, start with a resonable
  294. // default buffer size
  295. if(length == 0)
  296. length = IOBUFSIZE;
  297. SegmentBuffer seg = new SegmentBuffer((int)length + 1);
  298. InputStreamReader in = new InputStreamReader(_in,
  299. buffer.getStringProperty(Buffer.ENCODING));
  300. char[] buf = new char[IOBUFSIZE];
  301. // Number of characters in 'buf' array.
  302. // InputStream.read() doesn't always fill the
  303. // array (eg, the file size is not a multiple of
  304. // IOBUFSIZE, or it is a GZipped file, etc)
  305. int len;
  306. // True if a \n was read after a \r. Usually
  307. // means this is a DOS/Windows file
  308. boolean CRLF = false;
  309. // A \r was read, hence a MacOS file
  310. boolean CROnly = false;
  311. // Was the previous read character a \r?
  312. // If we read a \n and this is true, we assume
  313. // we have a DOS/Windows file
  314. boolean lastWasCR = false;
  315. // Number of lines read. Every 100 lines, we update the
  316. // progress bar
  317. int lineCount = 0;
  318. while((len = in.read(buf,0,buf.length)) != -1)
  319. {
  320. // Offset of previous line, relative to
  321. // the start of the I/O buffer (NOT
  322. // relative to the start of the document)
  323. int lastLine = 0;
  324. for(int i = 0; i < len; i++)
  325. {
  326. // Look for line endings.
  327. switch(buf[i])
  328. {
  329. case '\r':
  330. // If we read a \r and
  331. // lastWasCR is also true,
  332. // it is probably a Mac file
  333. // (\r\r in stream)
  334. if(lastWasCR)
  335. {
  336. CROnly = true;
  337. CRLF = false;
  338. }
  339. // Otherwise set a flag,
  340. // so that \n knows that last
  341. // was a \r
  342. else
  343. {
  344. lastWasCR = true;
  345. }
  346. // Insert a line
  347. seg.append(buf,lastLine,i -
  348. lastLine);
  349. endOffsets.add(seg.count);
  350. seg.append('\n');
  351. if(trackProgress && lineCount++ % PROGRESS_INTERVAL == 0)
  352. setProgressValue(seg.count);
  353. // This is i+1 to take the
  354. // trailing \n into account
  355. lastLine = i + 1;
  356. break;
  357. case '\n':
  358. // If lastWasCR is true,
  359. // we just read a \r followed
  360. // by a \n. We specify that
  361. // this is a Windows file,
  362. // but take no further
  363. // action and just ignore
  364. // the \r.
  365. if(lastWasCR)
  366. {
  367. CROnly = false;
  368. CRLF = true;
  369. lastWasCR = false;
  370. // Bump lastLine so
  371. // that the next line
  372. // doesn't erronously
  373. // pick up the \r
  374. lastLine = i + 1;
  375. }
  376. // Otherwise, we found a \n
  377. // that follows some other
  378. // character, hence we have
  379. // a Unix file
  380. else
  381. {
  382. CROnly = false;
  383. CRLF = false;
  384. seg.append(buf,lastLine,
  385. i - lastLine);
  386. endOffsets.add(seg.count);
  387. seg.append('\n');
  388. if(trackProgress && lineCount++ % PROGRESS_INTERVAL == 0)
  389. setProgressValue(seg.count);
  390. lastLine = i + 1;
  391. }
  392. break;
  393. default:
  394. // If we find some other
  395. // character that follows
  396. // a \r, so it is not a
  397. // Windows file, and probably
  398. // a Mac file
  399. if(lastWasCR)
  400. {
  401. CROnly = true;
  402. CRLF = false;
  403. lastWasCR = false;
  404. }
  405. break;
  406. }
  407. }
  408. if(trackProgress)
  409. setProgressValue(seg.count);
  410. // Add remaining stuff from buffer
  411. seg.append(buf,lastLine,len - lastLine);
  412. }
  413. setAbortable(false);
  414. String lineSeparator;
  415. if(CRLF)
  416. lineSeparator = "\r\n";
  417. else if(CROnly)
  418. lineSeparator = "\r";
  419. else
  420. lineSeparator = "\n";
  421. in.close();
  422. // Chop trailing newline and/or ^Z (if any)
  423. int bufferLength = seg.count;
  424. if(bufferLength != 0)
  425. {
  426. char ch = seg.array[bufferLength - 1];
  427. if(ch == 0x1a /* DOS ^Z */)
  428. seg.count--;
  429. }
  430. buffer.setBooleanProperty(Buffer.TRAILING_EOL,false);
  431. if(bufferLength != 0 && jEdit.getBooleanProperty("stripTrailingEOL"))
  432. {
  433. char ch = seg.array[bufferLength - 1];
  434. if(ch == '\n')
  435. {
  436. buffer.setBooleanProperty(Buffer.TRAILING_EOL,true);
  437. seg.count--;
  438. endOffsets.setSize(endOffsets.getSize() - 1);
  439. }
  440. }
  441. // to avoid having to deal with read/write locks and such,
  442. // we insert the loaded data into the buffer in the
  443. // post-load cleanup runnable, which runs in the AWT thread.
  444. buffer.setProperty(LOAD_DATA,seg);
  445. buffer.setProperty(END_OFFSETS,endOffsets);
  446. buffer.setProperty(NEW_PATH,path);
  447. buffer.setProperty(Buffer.LINESEP,lineSeparator);
  448. } //}}}
  449. //{{{ readMarkers() method
  450. private void readMarkers(Buffer buffer, InputStream _in)
  451. throws IOException
  452. {
  453. // For `reload' command
  454. buffer.removeAllMarkers();
  455. BufferedReader in = new BufferedReader(new InputStreamReader(_in));
  456. String line;
  457. while((line = in.readLine()) != null)
  458. {
  459. // compatibility kludge for jEdit 3.1 and earlier
  460. if(!line.startsWith("!"))
  461. continue;
  462. char shortcut = line.charAt(1);
  463. int start = line.indexOf(';');
  464. int end = line.indexOf(';',start + 1);
  465. int position = Integer.parseInt(line.substring(start + 1,end));
  466. buffer.addMarker(shortcut,position);
  467. }
  468. in.close();
  469. } //}}}
  470. //{{{ save() method
  471. private void save()
  472. {
  473. OutputStream out = null;
  474. try
  475. {
  476. String[] args = { vfs.getFileName(path) };
  477. setStatus(jEdit.getProperty("vfs.status.save",args));
  478. // the entire save operation can be aborted...
  479. setAbortable(true);
  480. try
  481. {
  482. path = vfs._canonPath(session,path,view);
  483. buffer.readLock();
  484. // Only backup once per session
  485. if(buffer.getProperty(Buffer.BACKED_UP) == null
  486. || jEdit.getBooleanProperty("backupEverySave"))
  487. {
  488. vfs._backup(session,path,view);
  489. buffer.setBooleanProperty(Buffer.BACKED_UP,true);
  490. }
  491. /* if the VFS supports renaming files, we first
  492. * save to #<filename>#save#, then rename that
  493. * to <filename>, so that if the save fails,
  494. * data will not be lost */
  495. String savePath;
  496. boolean twoStageSave = (vfs.getCapabilities() & VFS.RENAME_CAP) != 0
  497. && jEdit.getBooleanProperty("twoStageSave");
  498. if(twoStageSave)
  499. {
  500. savePath = MiscUtilities.constructPath(
  501. vfs.getParentOfPath(path),
  502. '#' + vfs.getFileName(path)
  503. + "#save#");
  504. }
  505. else
  506. savePath = path;
  507. out = vfs._createOutputStream(session,savePath,view);
  508. if(out != null)
  509. {
  510. // Can't use buffer.getName() here because
  511. // it is not changed until the save is
  512. // complete
  513. if(savePath.endsWith(".gz"))
  514. buffer.setBooleanProperty(Buffer.GZIPPED,true);
  515. if(buffer.getBooleanProperty(Buffer.GZIPPED))
  516. out = new GZIPOutputStream(out);
  517. write(buffer,out);
  518. if(twoStageSave)
  519. {
  520. if(!vfs._rename(session,savePath,path,view))
  521. throw new IOException(path);
  522. }
  523. // We only save markers to VFS's that support deletion.
  524. // Otherwise, we will accumilate stale marks files.
  525. if((vfs.getCapabilities() & VFS.DELETE_CAP) != 0)
  526. {
  527. if(jEdit.getBooleanProperty("persistentMarkers")
  528. && buffer.getMarkers().size() != 0)
  529. {
  530. setStatus(jEdit.getProperty("vfs.status.save-markers",args));
  531. setProgressValue(0);
  532. out = vfs._createOutputStream(session,markersPath,view);
  533. if(out != null)
  534. writeMarkers(buffer,out);
  535. }
  536. else
  537. vfs._delete(session,markersPath,view);
  538. }
  539. }
  540. else
  541. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  542. }
  543. catch(IOException io)
  544. {
  545. Log.log(Log.ERROR,this,io);
  546. String[] pp = { io.toString() };
  547. VFSManager.error(view,path,"ioerror.write-error",pp);
  548. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  549. }
  550. finally
  551. {
  552. buffer.readUnlock();
  553. }
  554. }
  555. catch(WorkThread.Abort a)
  556. {
  557. if(out != null)
  558. {
  559. try
  560. {
  561. out.close();
  562. }
  563. catch(IOException io)
  564. {
  565. }
  566. }
  567. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  568. }
  569. finally
  570. {
  571. try
  572. {
  573. vfs._saveComplete(session,buffer,view);
  574. vfs._endVFSSession(session,view);
  575. }
  576. catch(IOException io)
  577. {
  578. Log.log(Log.ERROR,this,io);
  579. String[] pp = { io.toString() };
  580. VFSManager.error(view,path,"ioerror.write-error",pp);
  581. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  582. }
  583. catch(WorkThread.Abort a)
  584. {
  585. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  586. }
  587. }
  588. } //}}}
  589. //{{{ autosave() method
  590. private void autosave()
  591. {
  592. OutputStream out = null;
  593. try
  594. {
  595. String[] args = { vfs.getFileName(path) };
  596. setStatus(jEdit.getProperty("vfs.status.autosave",args));
  597. // the entire save operation can be aborted...
  598. setAbortable(true);
  599. try
  600. {
  601. //buffer.readLock();
  602. if(!buffer.isDirty())
  603. {
  604. // buffer has been saved while we
  605. // were waiting.
  606. return;
  607. }
  608. out = vfs._createOutputStream(session,path,view);
  609. if(out == null)
  610. return;
  611. write(buffer,out);
  612. }
  613. catch(Exception e)
  614. {
  615. }
  616. finally
  617. {
  618. //buffer.readUnlock();
  619. }
  620. }
  621. catch(WorkThread.Abort a)
  622. {
  623. if(out != null)
  624. {
  625. try
  626. {
  627. out.close();
  628. }
  629. catch(IOException io)
  630. {
  631. }
  632. }
  633. }
  634. } //}}}
  635. //{{{ write() method
  636. private void write(Buffer buffer, OutputStream _out)
  637. throws IOException
  638. {
  639. BufferedWriter out = new BufferedWriter(
  640. new OutputStreamWriter(_out,
  641. buffer.getStringProperty(Buffer.ENCODING)),
  642. IOBUFSIZE);
  643. Segment lineSegment = new Segment();
  644. String newline = buffer.getStringProperty(Buffer.LINESEP);
  645. if(newline == null)
  646. newline = System.getProperty("line.separator");
  647. setProgressMaximum(buffer.getLineCount() / PROGRESS_INTERVAL);
  648. setProgressValue(0);
  649. int i = 0;
  650. while(i < buffer.getLineCount())
  651. {
  652. buffer.getLineText(i,lineSegment);
  653. out.write(lineSegment.array,lineSegment.offset,
  654. lineSegment.count);
  655. if(i != buffer.getLineCount() - 1)
  656. {
  657. out.write(newline);
  658. }
  659. if(++i % PROGRESS_INTERVAL == 0)
  660. setProgressValue(i / PROGRESS_INTERVAL);
  661. }
  662. if(jEdit.getBooleanProperty("stripTrailingEOL")
  663. && buffer.getBooleanProperty(Buffer.TRAILING_EOL))
  664. {
  665. out.write(newline);
  666. }
  667. out.close();
  668. } //}}}
  669. //{{{ writeMarkers() method
  670. private void writeMarkers(Buffer buffer, OutputStream out)
  671. throws IOException
  672. {
  673. Writer o = new BufferedWriter(new OutputStreamWriter(out));
  674. Vector markers = buffer.getMarkers();
  675. for(int i = 0; i < markers.size(); i++)
  676. {
  677. Marker marker = (Marker)markers.elementAt(i);
  678. o.write('!');
  679. o.write(marker.getShortcut());
  680. o.write(';');
  681. String pos = String.valueOf(marker.getPosition());
  682. o.write(pos);
  683. o.write(';');
  684. o.write(pos);
  685. o.write('\n');
  686. }
  687. o.close();
  688. } //}}}
  689. //{{{ insert() method
  690. private void insert()
  691. {
  692. InputStream in = null;
  693. try
  694. {
  695. try
  696. {
  697. String[] args = { vfs.getFileName(path) };
  698. setStatus(jEdit.getProperty("vfs.status.load",args));
  699. setAbortable(true);
  700. path = vfs._canonPath(session,path,view);
  701. VFS.DirectoryEntry entry = vfs._getDirectoryEntry(
  702. session,path,view);
  703. long length;
  704. if(entry != null)
  705. length = entry.length;
  706. else
  707. length = 0L;
  708. in = vfs._createInputStream(session,path,false,view);
  709. if(in == null)
  710. return;
  711. if(path.endsWith(".gz"))
  712. in = new GZIPInputStream(in);
  713. read(buffer,in,length);
  714. }
  715. catch(IOException io)
  716. {
  717. Log.log(Log.ERROR,this,io);
  718. String[] pp = { io.toString() };
  719. VFSManager.error(view,path,"ioerror.read-error",pp);
  720. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  721. }
  722. }
  723. catch(WorkThread.Abort a)
  724. {
  725. if(in != null)
  726. {
  727. try
  728. {
  729. in.close();
  730. }
  731. catch(IOException io)
  732. {
  733. }
  734. }
  735. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  736. }
  737. finally
  738. {
  739. try
  740. {
  741. vfs._endVFSSession(session,view);
  742. }
  743. catch(IOException io)
  744. {
  745. Log.log(Log.ERROR,this,io);
  746. String[] pp = { io.toString() };
  747. VFSManager.error(view,path,"ioerror.read-error",pp);
  748. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  749. }
  750. catch(WorkThread.Abort a)
  751. {
  752. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  753. }
  754. }
  755. } //}}}
  756. //}}}
  757. }