PageRenderTime 126ms CodeModel.GetById 106ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/gui/JEditHistoryModelSaver.java

#
Java | 224 lines | 156 code | 29 blank | 39 comment | 27 complexity | 13e30251960a8f3eb6e21a399de9c72b MD5 | raw file
  1/*
  2 * JEditHistoryModelSaver.java - Handles services.xml files in plugins
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2006 Matthieu Casanova
  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 */
 22package org.gjt.sp.jedit.gui;
 23
 24import org.gjt.sp.util.Log;
 25import org.gjt.sp.util.IOUtilities;
 26import org.gjt.sp.util.StandardUtilities;
 27import org.gjt.sp.jedit.MiscUtilities;
 28import org.gjt.sp.jedit.jEdit;
 29
 30import java.io.*;
 31import java.nio.charset.Charset;
 32import java.nio.charset.CharacterCodingException;
 33import java.util.*;
 34
 35/**
 36 * @author Matthieu Casanova
 37 * @version $Id: FoldHandler.java 5568 2006-07-10 20:52:23Z kpouer $
 38 */
 39public class JEditHistoryModelSaver implements HistoryModelSaver
 40{
 41	//{{{ load() method
 42	public Map<String, HistoryModel> load(Map<String, HistoryModel> models)
 43	{
 44		String settingsDirectory = jEdit.getSettingsDirectory();
 45		if(settingsDirectory == null)
 46			return models;
 47
 48		history = new File(MiscUtilities.constructPath(
 49			settingsDirectory,"history"));
 50		if(!history.exists())
 51			return models;
 52
 53		historyModTime = history.lastModified();
 54
 55		Log.log(Log.MESSAGE,HistoryModel.class,"Loading history");
 56
 57		if(models == null)
 58			models = Collections.synchronizedMap(new HashMap<String, HistoryModel>());
 59
 60		BufferedReader in = null;
 61		try
 62		{
 63			// Try loading with UTF-8 and fallback to the system
 64			// default encoding to load a history which was made by
 65			// an old version as well.
 66			try
 67			{
 68				// Pass the decoder explicitly to report a decode error
 69				// as an exception instead of replacing with \xFFFD.
 70				in = new BufferedReader(new InputStreamReader(
 71					new FileInputStream(history),
 72					Charset.forName("UTF-8").newDecoder()));
 73				models.putAll(loadFromReader(in));
 74			}
 75			catch(CharacterCodingException e)
 76			{
 77				// It seems to be made by an old version of jEdit.
 78				in.close();
 79				Log.log(Log.MESSAGE,HistoryModel.class,
 80					"Failed to load history with UTF-8." +
 81					" Fallbacking to the system default encoding.");
 82
 83				in = new BufferedReader(new FileReader(history));
 84				models.putAll(loadFromReader(in));
 85			}
 86		}
 87		catch(FileNotFoundException fnf)
 88		{
 89			//Log.log(Log.DEBUG,HistoryModel.class,fnf);
 90		}
 91		catch(IOException io)
 92		{
 93			Log.log(Log.ERROR,HistoryModel.class,io);
 94		}
 95		finally
 96		{
 97			IOUtilities.closeQuietly(in);
 98		}
 99		return models;
100	} //}}}
101
102	//{{{ save() method
103	public boolean save(Map<String, HistoryModel> models)
104	{
105		Log.log(Log.MESSAGE,HistoryModel.class,"Saving history");
106		File file1 = new File(MiscUtilities.constructPath(
107			jEdit.getSettingsDirectory(), "#history#save#"));
108		File file2 = new File(MiscUtilities.constructPath(
109			jEdit.getSettingsDirectory(), "history"));
110		if(file2.exists() && file2.lastModified() != historyModTime)
111		{
112			Log.log(Log.WARNING,HistoryModel.class,file2
113				+ " changed on disk; will not save history");
114			return false;
115		}
116
117		jEdit.backupSettingsFile(file2);
118
119		String lineSep = System.getProperty("line.separator");
120
121		BufferedWriter out = null;
122
123		try
124		{
125			out = new BufferedWriter(new OutputStreamWriter(
126				new FileOutputStream(file1), "UTF-8"));
127
128			if(models != null)
129			{
130				Collection<HistoryModel> values = models.values();
131				for (HistoryModel model : values)
132				{
133					if(model.getSize() == 0)
134						continue;
135
136					out.write('[');
137					out.write(StandardUtilities.charsToEscapes(
138						model.getName(),TO_ESCAPE));
139					out.write(']');
140					out.write(lineSep);
141
142					for(int i = 0; i < model.getSize(); i++)
143					{
144						out.write(StandardUtilities.charsToEscapes(
145							model.getItem(i),
146							TO_ESCAPE));
147						out.write(lineSep);
148					}
149				}
150			}
151
152			out.close();
153
154			/* to avoid data loss, only do this if the above
155			 * completed successfully */
156			file2.delete();
157			file1.renameTo(file2);
158		}
159		catch(IOException io)
160		{
161			Log.log(Log.ERROR,HistoryModel.class,io);
162		}
163		finally
164		{
165			IOUtilities.closeQuietly(out);
166		}
167
168		historyModTime = file2.lastModified();
169		return true;
170	} //}}}
171
172	//{{{ Private members
173	private static final String TO_ESCAPE = "\r\n\t\\\"'[]";
174	private static File history;
175	private static long historyModTime;
176
177	//{{{ loadFromReader() method
178	private static Map<String, HistoryModel> loadFromReader(BufferedReader in)
179		throws IOException
180	{
181		Map<String, HistoryModel> result = new HashMap<String, HistoryModel>();
182
183		HistoryModel currentModel = null;
184		String line;
185
186		while((line = in.readLine()) != null)
187		{
188			if(line.length() > 0 && line.charAt(0) == '[' && line.charAt(line.length() - 1) == ']')
189			{
190				if(currentModel != null)
191				{
192					result.put(currentModel.getName(),
193						currentModel);
194				}
195
196				String modelName = MiscUtilities
197					.escapesToChars(line.substring(
198					1,line.length() - 1));
199				currentModel = new HistoryModel(
200					modelName);
201			}
202			else if(currentModel == null)
203			{
204				throw new IOException("History data starts"
205					+ " before model name");
206			}
207			else
208			{
209				currentModel.addElement(MiscUtilities
210					.escapesToChars(line));
211			}
212		}
213
214		if(currentModel != null)
215		{
216			result.put(currentModel.getName(),currentModel);
217		}
218
219		return result;
220	} //}}}
221
222	//}}}
223
224}