OSDN Git Service

クリーンアップ
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / threads / SaveRunner.java
1 /*
2  * This file is part of NixNote/NeighborNote 
3  * Copyright 2009 Randy Baumgarte
4  * Copyright 2013 Yuki Takahashi
5  * 
6  * This file may be licensed under the terms of of the
7  * GNU General Public License Version 2 (the ``GPL'').
8  *
9  * Software distributed under the License is distributed
10  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
11  * express or implied. See the GPL for the specific language
12  * governing rights and limitations.
13  *
14  * You should have received a copy of the GPL along with this
15  * program. If not, go to http://www.gnu.org/licenses/gpl.html
16  * or write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19 */
20
21 package cx.fbn.nevernote.threads;
22
23 import java.util.GregorianCalendar;
24 import java.util.List;
25 import java.util.concurrent.LinkedBlockingQueue;
26
27 import com.evernote.edam.type.Resource;
28 import com.trolltech.qt.core.QMutex;
29 import com.trolltech.qt.core.QObject;
30
31 import cx.fbn.nevernote.Global;
32 import cx.fbn.nevernote.evernote.EnmlConverter;
33 import cx.fbn.nevernote.signals.NoteSignal;
34 import cx.fbn.nevernote.sql.DatabaseConnection;
35 import cx.fbn.nevernote.utilities.ApplicationLogger;
36 import cx.fbn.nevernote.utilities.Pair;
37
38 public class SaveRunner extends QObject implements Runnable {
39          
40         private final ApplicationLogger         logger;
41         public volatile boolean                         keepRunning;
42         public QMutex                                           threadLock;
43         private final DatabaseConnection        conn;
44         private boolean                                         idle;
45         public NoteSignal                                       noteSignals;
46
47         private volatile LinkedBlockingQueue<Pair<String, String>> workQueue = new LinkedBlockingQueue<Pair<String, String>>();
48         
49         
50         //*********************************************
51         //* Constructor                               *
52         //*********************************************
53         public SaveRunner(String logname, String u, String i, String r, String b, String uid, String pswd, String cpswd) {
54                 logger = new ApplicationLogger(logname);
55                 conn = new DatabaseConnection(logger, u, i, r, b, uid, pswd, cpswd, 0);
56                 threadLock = new QMutex();
57                 keepRunning = true;
58                 noteSignals = new NoteSignal();
59         }
60         
61         public SaveRunner(ApplicationLogger l, DatabaseConnection c) {
62                 logger = l;
63                 conn = c;
64                 keepRunning = true;
65                 noteSignals = new NoteSignal();
66         }
67         
68         
69         
70         //*********************************************
71         //* Run unit                                  *
72         //*********************************************
73         @Override
74         public void run() {
75                 thread().setPriority(Thread.MIN_PRIORITY);
76                 boolean keepRunning = true;
77                 
78                 while(keepRunning) {
79                         try {
80                                 Pair<String, String> content;
81                                 idle = true;
82                                 content = workQueue.take();
83                                 if (!content.getFirst().equalsIgnoreCase("stop")) {                                             
84                                         idle = false;
85                                         
86                                         // This is a bit of a hack.  It causes this thread to pause for 0.2 seconds.
87                                         // This helps make sure that the main thread gets to the
88                                         // database first when switching notes, othrewise it really 
89                                         // slows things down when fetching new notes.
90                                         GregorianCalendar now = new GregorianCalendar();
91                                         long prev = now.getTimeInMillis();
92                                         prev = prev+200;
93                                         while (prev>now.getTimeInMillis()) {
94                                                 now = new GregorianCalendar();                                          
95                                         }
96                                         
97                                         updateNoteContent(content.getFirst(), content.getSecond());
98                                 } else {
99                                         return;
100                                 }
101                                 threadLock.unlock();
102                         } catch (InterruptedException e) { }
103                 }
104                 conn.dbShutdown();
105         }
106         
107         
108         public synchronized void addWork(String guid, String content) {
109                 while(workQueue.size() > 0) {}
110                 Pair<String, String> pair = new Pair<String, String>(guid, content);
111                 workQueue.offer(pair);
112         }
113         
114         public synchronized void release(String guid, String content) {
115                 Pair<String, String> pair = new Pair<String, String>(guid, content);
116                 workQueue.add(pair);
117         }
118         
119         public synchronized int getWorkQueueSize() {
120                 return workQueue.size();
121         }
122
123         
124         //*********************************************
125         //* Getter & Setter method to tell the thread *
126         //* to keep running.                          *
127         //*********************************************
128         public void setKeepRunning(boolean b) {
129                 keepRunning = b;
130         }
131         public boolean keepRunning() {
132                 return keepRunning;
133         }
134         
135         public boolean isIdle() {
136                 return idle;
137         }
138         
139         
140         //*********************************************
141         //* Do the actual work                                *
142         //*********************************************
143         public void updateNoteContent(String guid, String content) {
144                 logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");
145                 
146                 // Actually save the content
147                 EnmlConverter enml = new EnmlConverter(logger);
148                 String newContent = enml.convert(guid, content);
149                 String fixedContent = enml.fixEnXMLCrap(newContent);
150                 if (fixedContent != null) {
151                         conn.getNoteTable().updateNoteContent(guid, fixedContent);
152                         logger.log(logger.EXTREME, "Saving new note resources");
153                         List<Resource> oldResources = conn.getNoteTable().noteResourceTable.getNoteResources(guid, false);
154                         List<String> newResources = enml.getResources();
155                         removeObsoleteResources(oldResources, newResources);
156                 } else {
157                         noteSignals.noteSaveRunnerError.emit(guid, null);
158                 }
159                 logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");
160         }
161         
162         // Remove resources that are no longer needed
163         private void removeObsoleteResources(List<Resource> oldResources, List<String> newResources) {
164                 if (oldResources == null || oldResources.size() == 0)
165                         return;
166                 if (newResources == null || newResources.size() == 0) {
167                         for (int i=0; i<oldResources.size(); i++) {
168                                 conn.getNoteTable().noteResourceTable.expungeNoteResource(oldResources.get(i).getGuid());
169                         }
170                 }
171                 for (int i=0; i<oldResources.size(); i++) {
172                         boolean matchFound = false;
173                         for (int j=0; j<newResources.size(); j++) {
174                                 if (newResources.get(j).equalsIgnoreCase(oldResources.get(i).getGuid())) 
175                                         matchFound = true;
176                                 if (Global.resourceMap.get(newResources.get(j))!= null) {
177                                         if (Global.resourceMap.get(newResources.get(j)).equalsIgnoreCase(oldResources.get(i).getGuid())) 
178                                                 matchFound = true;
179                                 }
180                                 if (matchFound)
181                                         j = newResources.size();
182                         }
183                         if (!matchFound)
184                                 conn.getNoteTable().noteResourceTable.expungeNoteResource(oldResources.get(i).getGuid());
185                 }
186         }
187 }