001: /*
002: * Session.java
003: *
004: * Copyright (C) 1998-2003 Peter Graves
005: * $Id: Session.java,v 1.11 2003/06/29 00:19:34 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import java.io.BufferedWriter;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.io.OutputStreamWriter;
028: import java.util.ArrayList;
029: import java.util.Iterator;
030: import java.util.List;
031: import org.xml.sax.Attributes;
032: import org.xml.sax.InputSource;
033: import org.xml.sax.SAXException;
034: import org.xml.sax.XMLReader;
035: import org.xml.sax.helpers.DefaultHandler;
036: import org.xml.sax.helpers.XMLReaderFactory;
037:
038: public final class Session extends DefaultHandler implements Constants {
039: private static File sessionDirectory;
040:
041: private final File file;
042:
043: private List bufferEntries;
044: private SessionBufferEntry currentBufferEntry;
045:
046: private Session() {
047: file = File.getInstance(Directories.getEditorDirectory(),
048: "session.xml");
049: }
050:
051: private Session(File file) {
052: this .file = file;
053: }
054:
055: public static File getSessionDirectory() {
056: if (sessionDirectory == null) {
057: sessionDirectory = File.getInstance(Directories
058: .getEditorDirectory(), "sessions");
059: if (!sessionDirectory.isDirectory()) {
060: sessionDirectory.mkdirs();
061: if (!sessionDirectory.isDirectory())
062: Log.error("unable to create session directory!");
063: }
064: }
065: return sessionDirectory;
066: }
067:
068: private static File getSessionFile(String name) {
069: return File.getInstance(getSessionDirectory(), name);
070: }
071:
072: public static Session getSession(String name) {
073: File file = getSessionFile(name);
074: if (file != null && file.isFile())
075: return new Session(file);
076: return null;
077: }
078:
079: public static Session getDefaultSession() {
080: return new Session();
081: }
082:
083: public static void saveDefaultSession() {
084: getDefaultSession().save();
085: }
086:
087: public static void saveCurrentSession() {
088: String name = Editor.getSessionName();
089: if (name != null) {
090: File file = getSessionFile(name);
091: if (file != null) {
092: Session session = new Session(file);
093: session.save();
094: }
095: }
096: }
097:
098: public static void saveSession() {
099: String name = Editor.getSessionName();
100: if (name == null) {
101: ChooseSessionDialog d = new ChooseSessionDialog(
102: "Save Session");
103: d.show();
104: name = d.getInput();
105: }
106: if (name != null)
107: saveSession(name);
108: }
109:
110: public static void saveSession(String name) {
111: File file = getSessionFile(name);
112: if (file != null) {
113: Session session = new Session(file);
114: session.save();
115: Editor.setSessionName(name);
116: Editor.currentEditor().status("Session saved");
117: }
118: }
119:
120: public static void loadSession() {
121: ChooseSessionDialog d = new ChooseSessionDialog("Load Session");
122: d.show();
123: String name = d.getInput();
124: if (name != null)
125: loadSession(name);
126: }
127:
128: public static void loadSession(String name) {
129: File file = getSessionFile(name);
130: if (file == null)
131: return;
132: if (!file.isFile()) {
133: String message = "File \"" + file.canonicalPath()
134: + "\" not found";
135: MessageDialog.showMessageDialog(message, "Load Session");
136: return;
137: }
138: final Editor editor = Editor.currentEditor();
139: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
140: if (!editor.okToClose(it.nextBuffer()))
141: return;
142: }
143: // Load new session.
144: Session session = new Session(file);
145: if (!session.load()) {
146: Log.error("unable to load session from " + file);
147: MessageDialog.showMessageDialog(
148: "Unable to load session from " + file,
149: "Load Session");
150: return;
151: }
152:
153: if (Editor.getSessionName() != null)
154: if (Editor.preferences().getBooleanProperty(
155: Property.AUTOSAVE_NAMED_SESSIONS))
156: saveCurrentSession();
157:
158: Marker.invalidateAllMarkers();
159:
160: editor.setWaitCursor();
161: // Close all the existing buffers.
162: for (BufferIterator iter = new BufferIterator(); iter.hasNext();) {
163: Buffer buf = iter.nextBuffer();
164: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
165: Editor ed = it.nextEditor();
166: ed.views.remove(buf);
167: }
168: buf.deleteAutosaveFile();
169: iter.remove();
170: buf.dispose();
171: }
172: editor.unsplitWindow();
173: Buffer toBeActivated = session.createBuffers();
174: // Make sure read-only status is correct for each buffer.
175: for (BufferIterator it = new BufferIterator(); it.hasNext();)
176: editor.reactivate(it.nextBuffer());
177: for (EditorIterator it = new EditorIterator(); it.hasNext();)
178: it.nextEditor().activate(toBeActivated);
179: Sidebar.setUpdateFlagInAllFrames(SIDEBAR_BUFFER_LIST_CHANGED);
180: Sidebar.refreshSidebarInAllFrames();
181: Editor.setSessionName(name);
182: editor.setDefaultCursor();
183: }
184:
185: public Buffer restore() {
186: if (file == null) {
187: Debug.bug();
188: return null;
189: }
190: if (!file.isFile())
191: return null;
192: if (!load()) {
193: Log.error("Session.restore unable to load " + file);
194: return null;
195: }
196: return createBuffers();
197: }
198:
199: private Buffer createBuffers() {
200: long start = System.currentTimeMillis();
201: Buffer toBeActivated = null;
202: long lastActivated = 0;
203: Iterator iter = bufferEntries.iterator();
204: while (iter.hasNext()) {
205: SessionBufferEntry entry = (SessionBufferEntry) iter.next();
206: if (entry != null) {
207: File file = File.getInstance(entry.getPath());
208: if (file != null && file.isLocal()) {
209: Buffer buf = null;
210: if (file.isDirectory())
211: buf = new Directory(file);
212: else if (file.isFile() && file.canRead()) {
213: if (entry.getModeId() == WEB_MODE)
214: buf = WebBuffer.createWebBuffer(file, null,
215: null);
216: else
217: buf = Buffer.precreateBuffer(file);
218: }
219: if (buf != null) {
220: buf.setLastView(new View(entry));
221: if (toBeActivated == null
222: || entry.getLastActivated() > lastActivated) {
223: toBeActivated = buf;
224: lastActivated = entry.getLastActivated();
225: }
226: }
227: } else {
228: Log.error("Session.createBuffers file = " + file);
229: Debug.bug();
230: }
231: }
232: }
233: if (toBeActivated == null)
234: toBeActivated = Editor.getBufferList().getFirstBuffer();
235: long elapsed = System.currentTimeMillis() - start;
236: Log.debug("createBuffers " + Editor.getBufferList().size()
237: + " buffers " + elapsed + " ms");
238: return toBeActivated;
239: }
240:
241: public void save() {
242: try {
243: File tempFile = Utilities.getTempFile();
244: BufferedWriter writer = new BufferedWriter(
245: new OutputStreamWriter(tempFile.getOutputStream()));
246: writer.write("<?xml version=\"1.0\"?>");
247: writer.newLine();
248: writer.write("<session version=\"" + getVersion() + "\">");
249: writer.newLine();
250: writer.write(" <buffers>");
251: writer.newLine();
252: int index = 0;
253: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
254: Buffer buf = it.nextBuffer();
255: // Skip shell, compilation, HTTP buffers etc.
256: if (!buf.canBeRestored())
257: continue;
258: // Skip untitled buffers.
259: if (buf.getFile() == null)
260: continue;
261: SessionBufferEntry entry = new SessionBufferEntry(buf,
262: index++);
263: writer.write(entry.toXml());
264: writer.newLine();
265: }
266: writer.write(" </buffers>");
267: writer.newLine();
268: writer.write("</session>");
269: writer.newLine();
270: writer.flush();
271: writer.close();
272: Utilities.deleteRename(tempFile, file);
273: } catch (IOException e) {
274: Log.error(e);
275: }
276: }
277:
278: private boolean load() {
279: InputStream inputStream = null;
280: try {
281: if (file != null && file.isFile())
282: inputStream = file.getInputStream();
283: } catch (IOException e) {
284: Log.error(e);
285: return false;
286: }
287: if (inputStream == null)
288: return false;
289: XMLReader xmlReader = Utilities.getDefaultXMLReader();
290: if (xmlReader == null)
291: return false;
292: xmlReader.setContentHandler(this );
293: try {
294: InputSource inputSource = new InputSource(inputStream);
295: xmlReader.parse(inputSource);
296: } catch (Exception e) {
297: Log.error(e);
298: return false;
299: }
300: if (bufferEntries == null)
301: return false;
302: // Make sure we can open at least one buffer.
303: Iterator iter = bufferEntries.iterator();
304: while (iter.hasNext()) {
305: SessionBufferEntry entry = (SessionBufferEntry) iter.next();
306: if (entry != null) {
307: File file = File.getInstance(entry.getPath());
308: Debug.assertTrue(file.isLocal());
309: if (file.exists())
310: return true;
311: }
312: }
313: return false;
314: }
315:
316: public void startElement(String uri, String localName,
317: String qName, Attributes attributes) throws SAXException {
318: if (localName.equals("buffer") || qName.equals("buffer")) {
319: currentBufferEntry = new SessionBufferEntry();
320: String path = attributes.getValue("", "path");
321: currentBufferEntry.setPath(path);
322: String mode = attributes.getValue("", "mode");
323: currentBufferEntry.setMode(mode);
324: String dot = attributes.getValue("", "dot");
325: int index = dot.indexOf(',');
326: if (index >= 0) {
327: String s1 = dot.substring(0, index);
328: String s2 = dot.substring(index + 1);
329: try {
330: currentBufferEntry.setDotLineNumber(Integer
331: .parseInt(s1));
332: currentBufferEntry.setDotOffset(Integer
333: .parseInt(s2));
334: } catch (NumberFormatException e) {
335: Log.error(e);
336: }
337: }
338: String when = attributes.getValue("", "when");
339: try {
340: currentBufferEntry.setLastActivated(Long
341: .parseLong(when));
342: } catch (NumberFormatException e) {
343: Log.error(e);
344: }
345: }
346: }
347:
348: public void endElement(String uri, String localName, String qName) {
349: if (localName.equals("buffer") || qName.equals("buffer")) {
350: if (bufferEntries == null)
351: bufferEntries = new ArrayList();
352: bufferEntries.add(currentBufferEntry);
353: }
354: }
355:
356: private final int getVersion() {
357: return 1;
358: }
359: }
|