2 * This file is part of NeighborNote
3 * Copyright 2013 Yuki Takahashi
5 * This file may be licensed under the terms of of the
6 * GNU General Public License Version 2 (the ``GPL'').
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.
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.
20 package cx.fbn.nevernote.threads;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.concurrent.LinkedBlockingQueue;
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.limits.Constants;
31 import com.evernote.edam.notestore.RelatedQuery;
32 import com.evernote.edam.notestore.RelatedResult;
33 import com.evernote.edam.notestore.RelatedResultSpec;
34 import com.evernote.edam.type.Note;
35 import com.evernote.thrift.TException;
36 import com.trolltech.qt.core.QMutex;
37 import com.trolltech.qt.core.QObject;
39 import cx.fbn.nevernote.Global;
40 import cx.fbn.nevernote.signals.ENRelatedNotesSignal;
41 import cx.fbn.nevernote.signals.LimitSignal;
42 import cx.fbn.nevernote.utilities.ApplicationLogger;
43 import cx.fbn.nevernote.utilities.Pair;
45 public class ENRelatedNotesRunner extends QObject implements Runnable{
47 private final ApplicationLogger logger;
48 private final SyncRunner syncRunner;
49 public volatile ENRelatedNotesSignal enRelatedNotesSignal;
51 private volatile boolean keepRunning;
52 private volatile LinkedBlockingQueue<String> workQueue;
53 private volatile LinkedBlockingQueue<Pair<String, List<String>>> resultQueue; // ペア<元ノートguid, 関連ノートguidリスト>を溜めておくキュー
54 public volatile LimitSignal limitSignal;
56 public ENRelatedNotesRunner(SyncRunner syncRunner, ApplicationLogger logger) {
58 this.syncRunner = syncRunner;
59 this.enRelatedNotesSignal = new ENRelatedNotesSignal();
60 this.mutex = new QMutex();
61 this.keepRunning = true;
62 this.workQueue = new LinkedBlockingQueue<String>();
63 this.resultQueue = new LinkedBlockingQueue<Pair<String, List<String>>>();
64 this.limitSignal = new LimitSignal();
69 thread().setPriority(Thread.MIN_PRIORITY);
71 logger.log(logger.MEDIUM, "ENRelatedNotesスレッド開始");
74 String work = workQueue.take();
76 if (work.startsWith("GET")) {
77 String guid = work.replace("GET ", "");
78 logger.log(logger.EXTREME, "Evernote関連ノート取得開始 guid = " + guid);
80 List<Note> relatedNotes = getENRelatedNotes(guid);
82 Pair<String, List<String>> resultPair = new Pair<String, List<String>>();
83 resultPair.setFirst(guid);
84 if (relatedNotes == null) { // 取得に失敗
85 logger.log(logger.EXTREME, "Evernote関連ノートの取得に失敗");
86 } else if (relatedNotes.isEmpty()) { // このノートにEvernote関連ノートは存在しない
87 logger.log(logger.EXTREME, "Evernote関連ノートの取得に成功 関連ノートは存在しなかった");
88 resultPair.setSecond(new ArrayList<String>());
89 } else { // Evernote関連ノートが存在する
90 logger.log(logger.EXTREME, "Evernote関連ノートの取得に成功 関連ノートは存在した");
91 List<String> relatedNoteGuids = new ArrayList<String>();
92 for (Note relatedNote : relatedNotes) {
93 relatedNoteGuids.add(relatedNote.getGuid());
95 resultPair.setSecond(relatedNoteGuids);
98 resultQueue.offer(resultPair);
99 enRelatedNotesSignal.getENRelatedNotesFinished.emit();
100 logger.log(logger.EXTREME, "Evernote関連ノート取得完了 guid = " + guid);
101 } else if (work.startsWith("STOP")) {
102 logger.log(logger.MEDIUM, "ENRelatedNotesスレッド停止");
106 } catch (InterruptedException e) {
107 // TODO 自動生成された catch ブロック
113 private List<Note> getENRelatedNotes(String guid) {
114 RelatedResult result = getENRelatedResult(guid);
115 List<Note> relatedNotes = new ArrayList<Note>();
117 if (result != null) {
118 relatedNotes = result.getNotes();
125 private RelatedResult getENRelatedResult(String guid) {
126 if (!Global.isConnected) {
130 RelatedQuery rquery = new RelatedQuery();
131 rquery.setNoteGuid(guid);
132 RelatedResultSpec resultSpec = new RelatedResultSpec();
133 resultSpec.setMaxNotes(Constants.EDAM_RELATED_MAX_NOTES);
134 if (syncRunner != null && syncRunner.localNoteStore != null) {
136 RelatedResult result = syncRunner.localNoteStore.findRelated(syncRunner.authToken, rquery, resultSpec);
138 } catch (EDAMUserException e) {
139 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMUserException");
140 } catch (EDAMSystemException e) {
141 if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) {
142 limitSignal.rateLimitReached.emit(e.getRateLimitDuration());
144 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMSystemException");
145 } catch (EDAMNotFoundException e) {
146 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMnotFoundException guid = " + guid);
147 } catch (TException e) {
148 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:TException");
154 public boolean isKeepRunning() {
158 public void setKeepRunning(boolean keepRunning) {
159 this.keepRunning = keepRunning;
162 public synchronized boolean addGuid(String guid) {
163 if (workQueue.offer("GET " + guid)) {
170 public synchronized boolean addStop() {
171 if (workQueue.offer("STOP")) {
177 public synchronized Pair<String, List<String>> getENRelatedNoteGuids() {
179 return resultQueue.take();
180 } catch (InterruptedException e) {
181 // TODO 自動生成された catch ブロック