OSDN Git Service

Evernote関連ノート取得数と連想ノート表示数を変更した
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / threads / ENRelatedNotesRunner.java
1 /*
2  * This file is part of NeighborNote
3  * Copyright 2013 Yuki Takahashi
4  * 
5  * This file may be licensed under the terms of of the
6  * GNU General Public License Version 2 (the ``GPL'').
7  *
8  * Software distributed under the License is distributed
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
10  * express or implied. See the GPL for the specific language
11  * governing rights and limitations.
12  *
13  * You should have received a copy of the GPL along with this
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html
15  * or write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18 */
19
20 package cx.fbn.nevernote.threads;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.LinkedBlockingQueue;
25
26 import com.evernote.edam.error.EDAMErrorCode;
27 import com.evernote.edam.error.EDAMNotFoundException;
28 import com.evernote.edam.error.EDAMSystemException;
29 import com.evernote.edam.error.EDAMUserException;
30 import com.evernote.edam.notestore.RelatedQuery;
31 import com.evernote.edam.notestore.RelatedResult;
32 import com.evernote.edam.notestore.RelatedResultSpec;
33 import com.evernote.edam.type.Note;
34 import com.evernote.thrift.TException;
35 import com.trolltech.qt.core.QMutex;
36 import com.trolltech.qt.core.QObject;
37
38 import cx.fbn.nevernote.Global;
39 import cx.fbn.nevernote.signals.ENRelatedNotesSignal;
40 import cx.fbn.nevernote.signals.LimitSignal;
41 import cx.fbn.nevernote.utilities.ApplicationLogger;
42 import cx.fbn.nevernote.utilities.Pair;
43
44 public class ENRelatedNotesRunner extends QObject implements Runnable{
45         
46         private final ApplicationLogger                                 logger;
47         private final SyncRunner                                                syncRunner;
48         public volatile ENRelatedNotesSignal                    enRelatedNotesSignal;
49         public QMutex                                                                   mutex;
50         private volatile boolean                                                keepRunning;
51         private volatile LinkedBlockingQueue<String>    workQueue;
52         private volatile LinkedBlockingQueue<Pair<String, List<String>>> resultQueue;   // ペア<元ノートguid, 関連ノートguidリスト>を溜めておくキュー
53         public volatile LimitSignal                                     limitSignal;
54         
55         public ENRelatedNotesRunner(SyncRunner syncRunner, String logname) {
56                 this.logger = new ApplicationLogger(logname);
57                 this.syncRunner = syncRunner;
58                 this.enRelatedNotesSignal = new ENRelatedNotesSignal();
59                 this.mutex = new QMutex();
60                 this.keepRunning = true;
61                 this.workQueue = new LinkedBlockingQueue<String>();
62                 this.resultQueue = new LinkedBlockingQueue<Pair<String, List<String>>>();
63                 this.limitSignal = new LimitSignal();
64         }
65
66         @Override
67         public void run() {
68                 thread().setPriority(Thread.MIN_PRIORITY);
69                 
70                 logger.log(logger.MEDIUM, "ENRelatedNotesスレッド開始");
71                 while (keepRunning) {
72                         try {
73                                 String work = workQueue.take();
74                                 mutex.lock();
75                                 if (work.startsWith("GET")) {
76                                         String guid = work.replace("GET ", "");
77                                         logger.log(logger.EXTREME, "Evernote関連ノート取得開始 guid = " + guid);
78                                         
79                                         List<Note> relatedNotes = getENRelatedNotes(guid);
80                                         
81                                         Pair<String, List<String>> resultPair = new Pair<String, List<String>>();
82                                         resultPair.setFirst(guid);
83                                         if (relatedNotes == null) {                             // 取得に失敗
84                                                 logger.log(logger.EXTREME, "Evernote関連ノートの取得に失敗");
85                                         } else if (relatedNotes.isEmpty()) {    // このノートにEvernote関連ノートは存在しない
86                                                 logger.log(logger.EXTREME, "Evernote関連ノートの取得に成功 関連ノートは存在しなかった");
87                                                 resultPair.setSecond(new ArrayList<String>());
88                                         } else {                                                                // Evernote関連ノートが存在する
89                                                 logger.log(logger.EXTREME, "Evernote関連ノートの取得に成功 関連ノートは存在した");
90                                                 List<String> relatedNoteGuids = new ArrayList<String>();
91                                                 for (Note relatedNote : relatedNotes) {
92                                                         relatedNoteGuids.add(relatedNote.getGuid());
93                                                 }
94                                                 resultPair.setSecond(relatedNoteGuids);
95                                         }
96                                         
97                                         resultQueue.offer(resultPair);
98                                         enRelatedNotesSignal.getENRelatedNotesFinished.emit();
99                                         logger.log(logger.EXTREME, "Evernote関連ノート取得完了 guid = " + guid);
100                                 } else if (work.startsWith("STOP")) {
101                                         logger.log(logger.MEDIUM, "ENRelatedNotesスレッド停止");
102                                         keepRunning = false;
103                                 }
104                                 mutex.unlock();
105                         } catch (InterruptedException e) {
106                                 // TODO 自動生成された catch ブロック
107                                 e.printStackTrace();
108                         }
109                 }
110         }
111         
112         private List<Note> getENRelatedNotes(String guid) {
113                 RelatedResult result = getENRelatedResult(guid);
114                 List<Note> relatedNotes = new ArrayList<Note>();
115                 
116                 if (result != null) {
117                         relatedNotes = result.getNotes();
118                         return relatedNotes;
119                 }
120                 
121                 return null;
122         }
123         
124         private RelatedResult getENRelatedResult(String guid) {
125                 if (!Global.isConnected) {
126                         return null;
127                 }
128                 
129                 RelatedQuery rquery = new RelatedQuery();
130                 rquery.setNoteGuid(guid);
131                 RelatedResultSpec resultSpec = new RelatedResultSpec();
132                 resultSpec.setMaxNotes(5);
133                 if (syncRunner != null && syncRunner.localNoteStore != null) {
134                         try {
135                                 RelatedResult result = syncRunner.localNoteStore.findRelated(syncRunner.authToken, rquery, resultSpec);
136                                 return result;
137                         } catch (EDAMUserException e) {
138                                 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMUserException");
139                         } catch (EDAMSystemException e) {
140                                 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
141                                         limitSignal.rateLimitReached.emit(e.getRateLimitDuration());
142                                 }
143                                 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMSystemException");
144                         } catch (EDAMNotFoundException e) {
145                                 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMnotFoundException guid = " + guid);
146                         } catch (TException e) {
147                                 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:TException");
148                         }
149                 }
150                 return null;
151         }
152
153         public boolean isKeepRunning() {
154                 return keepRunning;
155         }
156
157         public void setKeepRunning(boolean keepRunning) {
158                 this.keepRunning = keepRunning;
159         }
160         
161         public boolean addGuid(String guid) {
162                 if (workQueue.offer("GET " + guid)) {
163                         return true;
164                 }
165                 
166                 return false;
167         }
168         
169         public boolean addStop() {
170                 if (workQueue.offer("STOP")) {
171                         return true;
172                 }
173                 return false;
174         }
175         
176         public synchronized Pair<String, List<String>> getENRelatedNoteGuids() {
177                 try {
178                         return resultQueue.take();
179                 } catch (InterruptedException e) {
180                         // TODO 自動生成された catch ブロック
181                         e.printStackTrace();
182                 }
183                 
184                 return null;
185         }
186 }