KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > usertasks > AutoSaver


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.tasklist.usertasks;
21
22 import java.awt.event.ActionListener JavaDoc;
23 import java.awt.event.ActionEvent JavaDoc;
24 import java.io.BufferedOutputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.OutputStreamWriter JavaDoc;
28 import java.io.Writer JavaDoc;
29 import java.net.URISyntaxException JavaDoc;
30 import java.text.ParseException JavaDoc;
31 import java.util.logging.Level JavaDoc;
32 import javax.swing.Timer JavaDoc;
33 import javax.swing.event.ChangeEvent JavaDoc;
34 import javax.swing.event.ChangeListener JavaDoc;
35 import javax.swing.event.EventListenerList JavaDoc;
36 import net.fortuna.ical4j.model.ValidationException;
37 import org.netbeans.modules.tasklist.usertasks.model.UserTaskList;
38 import org.netbeans.modules.tasklist.usertasks.translators.ICalExportFormat;
39 import org.netbeans.modules.tasklist.usertasks.util.UTUtils;
40 import org.openide.DialogDisplayer;
41 import org.openide.NotifyDescriptor;
42 import org.openide.NotifyDescriptor.Message;
43 import org.openide.filesystems.FileLock;
44 import org.openide.filesystems.FileObject;
45 import org.openide.filesystems.FileUtil;
46 import org.openide.loaders.DataObject;
47 import org.openide.loaders.DataObjectNotFoundException;
48
49 /**
50  * Automatic saving for .ics files.
51  *
52  * @author Tor Norbye
53  * @author tl
54  */

55 public class AutoSaver {
56     private UserTaskList utl;
57     private EventListenerList JavaDoc listeners = new EventListenerList JavaDoc();
58
59     /**
60      * Has the options set changed such that we need to save
61      */

62     private boolean modified = false;
63         
64     /** File being shown in this tasklist */
65     private FileObject file = null;
66     
67     /**
68      * Timer which keeps track of outstanding save requests - that way
69      * deleting multiple items for example will not cause multiple saves.
70      */

71     private Timer JavaDoc runTimer = null;
72     
73     private boolean enabled = false;
74     private DataObject do_;
75
76     /**
77      * Creates a new instance of AutoSaver.
78      *
79      * @param utl a task list
80      * @param file target file
81      */

82     public AutoSaver(UserTaskList utl, FileObject file) {
83         try {
84             this.do_ = DataObject.find(file);
85         } catch (DataObjectNotFoundException e) {
86             UTUtils.LOGGER.log(Level.SEVERE, e.getMessage(), e);
87         }
88         this.utl = utl;
89         this.file = file;
90         this.utl.addChangeListener(new ChangeListener JavaDoc() {
91             public void stateChanged(ChangeEvent JavaDoc ev) {
92                 do_.setModified(true);
93                 if (modified != true) {
94                     UTUtils.LOGGER.fine("modified = true"); // NOI18N
95
modified = true;
96                     fireChange();
97                 }
98                 if (enabled)
99                     scheduleWrite();
100             }
101         });
102     }
103     
104     /**
105      * Is automatic saving enabled?
106      *
107      * @return true = yes
108      */

109     public boolean isEnabled() {
110         return enabled;
111     }
112     
113     /**
114      * Enable/disable automatic saving.
115      *
116      * @param enabled true = save automatically
117      */

118     public void setEnabled(boolean enabled) {
119         this.enabled = enabled;
120     }
121     
122     /**
123      * Location of the tasklist
124      */

125     public FileObject getFile() {
126         return file;
127     }
128     
129     /**
130      * Schedule a document save
131      */

132     private void scheduleWrite() {
133         // Stop our current timer; the previous node has not
134
// yet been scanned; too brief an interval
135
if (runTimer != null) {
136         runTimer.stop();
137         runTimer = null;
138     }
139         ActionListener JavaDoc al = new ActionListener JavaDoc() {
140             public void actionPerformed(ActionEvent JavaDoc evt) {
141                 runTimer = null;
142                 try {
143                     save();
144                 } catch (IOException JavaDoc ioe) {
145                     DialogDisplayer.getDefault().notify(new Message(ioe,
146                             NotifyDescriptor.ERROR_MESSAGE));
147                 }
148             }
149         };
150         // 0.3 second delay
151
runTimer = new Timer JavaDoc(300, al);
152     runTimer.setRepeats(false);
153     runTimer.setCoalesce(true);
154     runTimer.start();
155     }
156
157     /**
158      * Was the task list modified since last saving?
159      *
160      * @return true = modified
161      */

162     public boolean isModified() {
163         return modified;
164     }
165     
166     /**
167      * Write the list to iCal.
168      */

169     public void save() throws IOException JavaDoc {
170         ICalExportFormat io = new ICalExportFormat();
171         
172         FileLock lock = this.file.lock();
173         try {
174             Writer JavaDoc w = new OutputStreamWriter JavaDoc(new BufferedOutputStream JavaDoc(
175                     file.getOutputStream(lock)), "UTF-8"); // NOI18N
176
try {
177                 io.writeList(utl, w, false);
178             } catch (ParseException JavaDoc e) {
179                 throw new IOException JavaDoc(e.getMessage());
180             } catch (URISyntaxException JavaDoc e) {
181                 throw new IOException JavaDoc(e.getMessage());
182             } catch (ValidationException e) {
183                 throw new IOException JavaDoc(e.getMessage());
184             } finally {
185                 try {
186                     w.close();
187                 } catch (IOException JavaDoc e) {
188                     UTUtils.LOGGER.log(Level.WARNING,
189                             "failed closing file", e); // NOI18N
190
}
191             }
192         } finally {
193             lock.releaseLock();
194         }
195
196         // Remove permissions for others on the file when on Unix
197
// varieties
198
if (new File JavaDoc("/bin/chmod").exists()) { // NOI18N
199
try {
200                 Runtime.getRuntime().exec(
201                      new String JavaDoc[] {"/bin/chmod", "go-rwx", // NOI18N
202
FileUtil.toFile(this.file).getAbsolutePath()});
203             } catch (Exception JavaDoc e) {
204                 // Silently accept
205
UTUtils.LOGGER.log(Level.INFO,
206                         "chmod call failed", e); // NOI18N
207
}
208         }
209
210         if (modified != false) {
211             modified = false;
212             do_.setModified(false);
213             UTUtils.LOGGER.fine("modified = false"); // NOI18N
214
fireChange();
215         }
216     }
217     
218     /**
219      * Returns the task list associated with this AutoSaver.
220      *
221      * @return task list
222      */

223     public UserTaskList getUserTaskList() {
224         return utl;
225     }
226     
227     
228     /**
229      * Adds a change listener. The listener will be notified whenever the
230      * modified flag changes.
231      *
232      * @param l a listener
233      */

234     public void addChangeListener(ChangeListener JavaDoc l) {
235         listeners.add(ChangeListener JavaDoc.class, l);
236     }
237     
238     /**
239      * Removes a change listener.
240      *
241      * @param l a listener.
242      */

243     public void removeChangeListener(ChangeListener JavaDoc l) {
244         listeners.remove(ChangeListener JavaDoc.class, l);
245     }
246     
247     /**
248      * Fires a ChangeEvent
249      */

250     void fireChange() {
251         // Guaranteed to return a non-null array
252
Object JavaDoc[] list = listeners.getListenerList();
253
254         // Process the listeners last to first, notifying
255
// those that are interested in this event
256
ChangeEvent JavaDoc changeEvent = null;
257         for (int i = list.length - 2; i >= 0; i -= 2) {
258             if (list[i] == ChangeListener JavaDoc.class) {
259                 // Lazily create the event:
260
if (changeEvent == null)
261                     changeEvent = new ChangeEvent JavaDoc(this);
262                 ((ChangeListener JavaDoc) list[i+1]).stateChanged(changeEvent);
263             }
264         }
265     }
266 }
267
Popular Tags