PageRenderTime 315ms CodeModel.GetById 41ms RepoModel.GetById 17ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/bufferio/BufferLoadRequest.java

#
Java | 394 lines | 288 code | 29 blank | 77 comment | 34 complexity | d18bbe27f1730cf848c2bbba17e71400 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. * BufferLoadRequest.java - I/O request
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2000, 2005 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.bufferio;
  23. //{{{ Imports
  24. import java.io.*;
  25. import java.nio.charset.*;
  26. import java.util.List;
  27. import java.util.ArrayList;
  28. import java.util.Set;
  29. import java.util.HashSet;
  30. import java.util.zip.GZIPInputStream;
  31. import org.gjt.sp.jedit.io.*;
  32. import org.gjt.sp.jedit.*;
  33. import org.gjt.sp.jedit.buffer.JEditBuffer;
  34. import org.gjt.sp.util.*;
  35. //}}}
  36. /**
  37. * A buffer load request.
  38. * @author Slava Pestov
  39. * @version $Id: BufferLoadRequest.java 17734 2010-05-04 22:08:41Z kpouer $
  40. */
  41. public class BufferLoadRequest extends BufferIORequest
  42. {
  43. //{{{ BufferLoadRequest constructor
  44. /**
  45. * Creates a new buffer I/O request.
  46. * @param view The view
  47. * @param buffer The buffer
  48. * @param session The VFS session
  49. * @param vfs The VFS
  50. * @param path The path
  51. */
  52. public BufferLoadRequest(View view, Buffer buffer,
  53. Object session, VFS vfs, String path)
  54. {
  55. super(view,buffer,session,vfs,path);
  56. } //}}}
  57. //{{{ run() method
  58. public void run()
  59. {
  60. try
  61. {
  62. setAbortable(true);
  63. if(!buffer.isTemporary())
  64. {
  65. String[] args = { vfs.getFileName(path) };
  66. setStatus(jEdit.getProperty("vfs.status.load",args));
  67. setValue(0L);
  68. }
  69. path = vfs._canonPath(session,path,view);
  70. readContents();
  71. buffer.setNewFile(false);
  72. if (jEdit.getBooleanProperty("persistentMarkers") &&
  73. (vfs.isMarkersFileSupported()))
  74. {
  75. InputStream markers = null;
  76. try
  77. {
  78. String[] args = { vfs.getFileName(path) };
  79. if(!buffer.isTemporary())
  80. setStatus(jEdit.getProperty("vfs.status.load-markers",args));
  81. setAbortable(true);
  82. markers = vfs._createInputStream(session,markersPath,true,view);
  83. if(markers != null)
  84. readMarkers(buffer,markers);
  85. }
  86. catch(Exception e)
  87. {
  88. // ignore
  89. }
  90. finally
  91. {
  92. IOUtilities.closeQuietly(markers);
  93. }
  94. }
  95. }
  96. catch(Exception e)
  97. {
  98. Log.log(Log.ERROR,this,e);
  99. Object[] pp = { e.toString() };
  100. VFSManager.error(view,path,"ioerror.read-error",pp);
  101. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  102. }
  103. catch(OutOfMemoryError oom)
  104. {
  105. Log.log(Log.ERROR,this,oom);
  106. VFSManager.error(view,path,"out-of-memory-error",null);
  107. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  108. }
  109. catch(WorkThread.Abort a)
  110. {
  111. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  112. }
  113. finally
  114. {
  115. try
  116. {
  117. vfs._endVFSSession(session,view);
  118. }
  119. catch(Exception e)
  120. {
  121. Log.log(Log.ERROR,this,e);
  122. String[] pp = { e.toString() };
  123. VFSManager.error(view,path,"ioerror.read-error",pp);
  124. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  125. }
  126. catch(WorkThread.Abort a)
  127. {
  128. buffer.setBooleanProperty(ERROR_OCCURRED,true);
  129. }
  130. }
  131. } //}}}
  132. //{{{ getNakedStream() method
  133. /**
  134. * Returns the raw contents stream for this load request.
  135. * This stream is not buffered or unzipped.
  136. */
  137. private InputStream getNakedStream() throws IOException
  138. {
  139. InputStream in = vfs._createInputStream(session,path,false,view);
  140. if(in != null)
  141. {
  142. return in;
  143. }
  144. throw new IOException("Unable to get a Stream for " + path);
  145. } //}}}
  146. //{{{ getContentLength() method
  147. /**
  148. * Returns content length of this load request.
  149. */
  150. private long getContentLength() throws IOException
  151. {
  152. VFSFile entry = vfs._getFile(session,path,view);
  153. if(entry != null)
  154. return entry.getLength();
  155. else
  156. return 0L;
  157. } //}}}
  158. //{{{ rewindContentsStream() method
  159. /**
  160. * Returns rewinded contents stream.
  161. * This method assumes the marked stream was made by
  162. * getMarkedStream() method. The stream may be reopened if reset()
  163. * failed.
  164. */
  165. private BufferedInputStream rewindContentsStream(BufferedInputStream markedStream, boolean gzipped)
  166. throws IOException
  167. {
  168. try
  169. {
  170. markedStream.reset();
  171. return markedStream;
  172. }
  173. catch(IOException e)
  174. {
  175. Log.log(Log.NOTICE, this
  176. , path + ": Reopening to rewind the stream");
  177. // Reopen the stream because the mark has been
  178. // invalidated while previous reading.
  179. markedStream.close();
  180. InputStream in = getNakedStream();
  181. try
  182. {
  183. if(gzipped)
  184. {
  185. in = new GZIPInputStream(in);
  186. }
  187. BufferedInputStream result
  188. = AutoDetection.getMarkedStream(in);
  189. in = null;
  190. return result;
  191. }
  192. finally
  193. {
  194. IOUtilities.closeQuietly(in);
  195. }
  196. }
  197. } //}}}
  198. //{{{ readContents() method
  199. /**
  200. * Read the contents of this load request.
  201. * Some auto detection is performed if enabled.
  202. * - GZIPed file
  203. * - The encoding
  204. * If fallback encodings are specified, they are used on
  205. * encoding errors.
  206. */
  207. private void readContents() throws IOException
  208. {
  209. long length = getContentLength();
  210. BufferedInputStream markedStream
  211. = AutoDetection.getMarkedStream(getNakedStream());
  212. try
  213. {
  214. boolean gzipped = false;
  215. // encodingProviders is consist of given
  216. // encodings as String or contents-aware
  217. // detectors as EncodingDetector.
  218. List<Object> encodingProviders
  219. = new ArrayList<Object>();
  220. boolean autodetect = buffer.getBooleanProperty(Buffer.ENCODING_AUTODETECT);
  221. if(autodetect)
  222. {
  223. gzipped = AutoDetection.isGzipped(markedStream);
  224. markedStream.reset();
  225. encodingProviders.addAll(AutoDetection.getEncodingDetectors());
  226. // If the detected encoding fail, fallback to
  227. // the original encoding.
  228. encodingProviders.add(buffer.getStringProperty(JEditBuffer.ENCODING));
  229. String fallbackEncodings = jEdit.getProperty("fallbackEncodings");
  230. if(fallbackEncodings != null && fallbackEncodings.length() > 0)
  231. {
  232. for(String encoding: fallbackEncodings.split("\\s+"))
  233. {
  234. encodingProviders.add(encoding);
  235. }
  236. }
  237. }
  238. else
  239. {
  240. gzipped = buffer.getBooleanProperty(Buffer.GZIPPED);
  241. encodingProviders.add(buffer.getStringProperty(JEditBuffer.ENCODING));
  242. }
  243. if(gzipped)
  244. {
  245. Log.log(Log.DEBUG, this, path + ": Stream is gzipped.");
  246. markedStream = AutoDetection.getMarkedStream(
  247. new GZIPInputStream(markedStream));
  248. }
  249. Set<String> failedEncodings = new HashSet<String>();
  250. Exception encodingError = null;
  251. for(Object encodingProvider: encodingProviders)
  252. {
  253. String encoding = null;
  254. if (encodingProvider instanceof String)
  255. {
  256. encoding = (String)encodingProvider;
  257. }
  258. else if(encodingProvider instanceof EncodingDetector)
  259. {
  260. markedStream = rewindContentsStream(markedStream, gzipped);
  261. encoding = ((EncodingDetector)encodingProvider).detectEncoding(new BufferedInputStream(markedStream));
  262. }
  263. else
  264. {
  265. Log.log(Log.DEBUG, this, "Strange encodingProvider: " + encodingProvider);
  266. }
  267. if(encoding == null || encoding.length() <= 0
  268. || failedEncodings.contains(encoding))
  269. {
  270. continue;
  271. }
  272. markedStream = rewindContentsStream(markedStream, gzipped);
  273. try
  274. {
  275. read(EncodingServer.getTextReader(markedStream, encoding)
  276. , length, false);
  277. if(autodetect)
  278. {
  279. // Store the successful properties.
  280. if(gzipped)
  281. {
  282. buffer.setBooleanProperty(Buffer.GZIPPED,true);
  283. }
  284. buffer.setProperty(JEditBuffer.ENCODING, encoding);
  285. }
  286. return;
  287. }
  288. catch(CharConversionException e)
  289. {
  290. encodingError = e;
  291. }
  292. catch(CharacterCodingException e)
  293. {
  294. encodingError = e;
  295. }
  296. catch(UnsupportedEncodingException e)
  297. {
  298. encodingError = e;
  299. }
  300. catch(UnsupportedCharsetException e)
  301. {
  302. encodingError = e;
  303. }
  304. Log.log(Log.NOTICE, this, path + ": " + encoding
  305. + ": " + encodingError);
  306. failedEncodings.add(encoding);
  307. }
  308. // All possible detectors and encodings failed.
  309. Object[] pp = { TextUtilities.join(failedEncodings,","), "" };
  310. if(failedEncodings.size() < 2)
  311. {
  312. pp[1] = encodingError.toString();
  313. }
  314. else
  315. {
  316. pp[1] = "See details in Activity Log";
  317. }
  318. VFSManager.error(view,path,"ioerror.encoding-error",pp);
  319. markedStream = rewindContentsStream(markedStream, gzipped);
  320. read(EncodingServer.getEncoding(
  321. buffer.getStringProperty(JEditBuffer.ENCODING)
  322. ).getPermissiveTextReader(markedStream)
  323. , length, false);
  324. if(autodetect && gzipped)
  325. {
  326. buffer.setBooleanProperty(Buffer.GZIPPED,true);
  327. }
  328. }
  329. finally
  330. {
  331. markedStream.close();
  332. }
  333. } //}}}
  334. //{{{ readMarkers() method
  335. private static void readMarkers(Buffer buffer, InputStream _in)
  336. throws IOException
  337. {
  338. // For `reload' command
  339. buffer.removeAllMarkers();
  340. BufferedReader in = new BufferedReader(new InputStreamReader(_in));
  341. try
  342. {
  343. String line;
  344. while((line = in.readLine()) != null)
  345. {
  346. // malformed marks file?
  347. if(line.length() == 0)
  348. continue;
  349. // compatibility kludge for jEdit 3.1 and earlier
  350. if(line.charAt(0) != '!')
  351. continue;
  352. char shortcut = line.charAt(1);
  353. int start = line.indexOf(';');
  354. int end = line.indexOf(';',start + 1);
  355. int position = Integer.parseInt(line.substring(start + 1,end));
  356. buffer.addMarker(shortcut,position);
  357. }
  358. buffer.setMarkersChanged(false);
  359. }
  360. finally
  361. {
  362. in.close();
  363. }
  364. } //}}}
  365. }