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.EDAMNotFoundException;
27 import com.evernote.edam.error.EDAMSystemException;
28 import com.evernote.edam.error.EDAMUserException;
29 import com.evernote.edam.limits.Constants;
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;
38 import cx.fbn.nevernote.Global;
39 import cx.fbn.nevernote.signals.ENRelatedNotesSignal;
40 import cx.fbn.nevernote.utilities.ApplicationLogger;
41 import cx.fbn.nevernote.utilities.Pair;
43 public class ENRelatedNotesRunner extends QObject implements Runnable{
45 private final ApplicationLogger logger;
46 private final SyncRunner syncRunner;
47 public volatile ENRelatedNotesSignal enRelatedNotesSignal;
49 private volatile boolean keepRunning;
50 private volatile LinkedBlockingQueue<String> workQueue;
51 private volatile LinkedBlockingQueue<Pair<String, List<String>>> resultQueue; // ペア<元ノートguid, 関連ノートguidリスト>を溜めておくキュー
53 public ENRelatedNotesRunner(SyncRunner syncRunner, ApplicationLogger logger) {
55 this.syncRunner = syncRunner;
56 this.enRelatedNotesSignal = new ENRelatedNotesSignal();
57 this.mutex = new QMutex();
58 this.keepRunning = true;
59 this.workQueue = new LinkedBlockingQueue<String>();
60 this.resultQueue = new LinkedBlockingQueue<Pair<String, List<String>>>();
65 thread().setPriority(Thread.MIN_PRIORITY);
67 logger.log(logger.MEDIUM, "ENRelatedNotesスレッド開始");
70 String work = workQueue.take();
72 if (work.startsWith("GET")) {
73 String guid = work.replace("GET ", "");
74 logger.log(logger.EXTREME, "Evernote関連ノート取得開始 guid = " + guid);
76 List<Note> relatedNotes = getENRelatedNotes(guid);
78 Pair<String, List<String>> resultPair = new Pair<String, List<String>>();
79 resultPair.setFirst(guid);
80 if (relatedNotes == null) { // 取得に失敗
81 logger.log(logger.EXTREME, "Evernote関連ノートの取得に失敗");
82 } else if (relatedNotes.isEmpty()) { // このノートにEvernote関連ノートは存在しない
83 logger.log(logger.EXTREME, "Evernote関連ノートの取得に成功 関連ノートは存在しなかった");
84 resultPair.setSecond(new ArrayList<String>());
85 } else { // Evernote関連ノートが存在する
86 logger.log(logger.EXTREME, "Evernote関連ノートの取得に成功 関連ノートは存在した");
87 List<String> relatedNoteGuids = new ArrayList<String>();
88 for (Note relatedNote : relatedNotes) {
89 relatedNoteGuids.add(relatedNote.getGuid());
91 resultPair.setSecond(relatedNoteGuids);
94 resultQueue.offer(resultPair);
95 enRelatedNotesSignal.getENRelatedNotesFinished.emit();
96 logger.log(logger.EXTREME, "Evernote関連ノート取得完了 guid = " + guid);
97 } else if (work.startsWith("STOP")) {
98 logger.log(logger.MEDIUM, "ENRelatedNotesスレッド停止");
102 } catch (InterruptedException e) {
103 // TODO 自動生成された catch ブロック
109 private List<Note> getENRelatedNotes(String guid) {
110 RelatedResult result = getENRelatedResult(guid);
111 List<Note> relatedNotes = new ArrayList<Note>();
113 if (result != null) {
114 relatedNotes = result.getNotes();
121 private RelatedResult getENRelatedResult(String guid) {
122 if (!Global.isConnected) {
126 RelatedQuery rquery = new RelatedQuery();
127 rquery.setNoteGuid(guid);
128 RelatedResultSpec resultSpec = new RelatedResultSpec();
129 resultSpec.setMaxNotes(Constants.EDAM_RELATED_MAX_NOTES);
130 if (syncRunner != null && syncRunner.localNoteStore != null) {
132 RelatedResult result = syncRunner.localNoteStore.findRelated(syncRunner.authToken, rquery, resultSpec);
134 } catch (EDAMUserException e) {
135 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMUserException");
136 } catch (EDAMSystemException e) {
137 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMSystemException");
138 } catch (EDAMNotFoundException e) {
139 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:EDAMnotFoundException guid = " + guid);
140 } catch (TException e) {
141 logger.log(logger.HIGH, "Evernote関連ノート取得中に例外発生:TException");
147 public boolean isKeepRunning() {
151 public void setKeepRunning(boolean keepRunning) {
152 this.keepRunning = keepRunning;
155 public synchronized boolean addGuid(String guid) {
156 if (workQueue.offer("GET " + guid)) {
163 public synchronized boolean addStop() {
164 if (workQueue.offer("STOP")) {
170 public synchronized Pair<String, List<String>> getENRelatedNoteGuids() {
172 return resultQueue.take();
173 } catch (InterruptedException e) {
174 // TODO 自動生成された catch ブロック