/* * This file is part of NixNote/NeighborNote * Copyright 2009 Randy Baumgarte * Copyright 2013 Yuki Takahashi * * This file may be licensed under the terms of of the * GNU General Public License Version 2 (the ``GPL''). * * Software distributed under the License is distributed * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either * express or implied. See the GPL for the specific language * governing rights and limitations. * * You should have received a copy of the GPL along with this * program. If not, go to http://www.gnu.org/licenses/gpl.html * or write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package cx.fbn.nevernote.threads; import java.util.ArrayList; import java.util.List; import java.util.Vector; import java.util.concurrent.LinkedBlockingQueue; import com.evernote.edam.type.Note; import com.trolltech.qt.core.QMutex; import com.trolltech.qt.core.QObject; import cx.fbn.nevernote.filters.NotebookCounter; import cx.fbn.nevernote.filters.TagCounter; import cx.fbn.nevernote.signals.NotebookSignal; import cx.fbn.nevernote.signals.TagSignal; import cx.fbn.nevernote.signals.TrashSignal; import cx.fbn.nevernote.sql.DatabaseConnection; import cx.fbn.nevernote.utilities.ApplicationLogger; public class CounterRunner extends QObject implements Runnable { private class NoteRecord { public String notebookGuid; public Vector<String> tags; public boolean active; public NoteRecord() { tags = new Vector<String>(); } } private final ApplicationLogger logger; private volatile boolean keepRunning; public int ID; public volatile NotebookSignal notebookSignal; public volatile TrashSignal trashSignal; public volatile TagSignal tagSignal; private volatile Vector<NoteRecord> records; public int type; public QMutex threadLock; public static int EXIT=0; public static int NOTEBOOK=1; public static int TAG=2; public static int TRASH=3; public boolean ready = false; public boolean abortCount = false; private final DatabaseConnection conn; private volatile LinkedBlockingQueue<Integer> readyQueue = new LinkedBlockingQueue<Integer>(); //********************************************* //* Constructor * //********************************************* public CounterRunner(String logname, int t, String u, String i, String r, String b, String uid, String pswd, String cpswd) { type = t; threadLock = new QMutex(); logger = new ApplicationLogger(logname); // setAutoDelete(false); conn = new DatabaseConnection(logger, u, i, r, b, uid, pswd, cpswd, 300); keepRunning = true; notebookSignal = new NotebookSignal(); tagSignal = new TagSignal(); trashSignal = new TrashSignal(); records = new Vector<NoteRecord>(); } //********************************************* //* Run unit * //********************************************* @Override public void run() { boolean keepRunning = true; thread().setPriority(Thread.MIN_PRIORITY); while(keepRunning) { ready = true; try { type = readyQueue.take(); threadLock.lock(); if (type == EXIT) keepRunning = false; if (type == NOTEBOOK) countNotebookResults(); if (type == TAG) countTagResults(); if (type == TRASH) countTrashResults(); threadLock.unlock(); } catch (InterruptedException e) {} } conn.dbShutdown(); } public void setNoteIndex(List<Note> idx) { abortCount = true; threadLock.lock(); abortCount = false; records.clear(); if (idx != null) { for (int i=0; i<idx.size(); i++) { if (abortCount) return; NoteRecord record = new NoteRecord(); record.notebookGuid = new String(idx.get(i).getNotebookGuid()); record.active = idx.get(i).isActive(); for (int j=0; j<idx.get(i).getTagGuidsSize(); j++) { if (abortCount) return; record.tags.add(new String(idx.get(i).getTagGuids().get(j))); } records.add(record); } } threadLock.unlock(); } public void release(int type) { readyQueue.add(type); } //********************************************* //* Getter & Setter method to tell the thread * //* to keep running. * //********************************************* public void setKeepRunning(boolean b) { keepRunning = b; } public boolean keepRunning() { return keepRunning; } //********************************************* //* Do the actual counting * //********************************************* private void countNotebookResults() { logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults"); if (abortCount) return; List<NotebookCounter> nCounter = new ArrayList<NotebookCounter>(); for (int i=0; i<records.size(); i++) { if (abortCount) return; boolean found = false; for (int j=0; j<nCounter.size(); j++) { if (abortCount) return; if (records.get(i).active && nCounter.get(j).getGuid().equals(records.get(i).notebookGuid)) { nCounter.get(j).setCount(nCounter.get(j).getCount()+1); found = true; j=nCounter.size(); } } if (!found && records.get(i).active) { NotebookCounter newCounter = new NotebookCounter(); newCounter.setGuid(records.get(i).notebookGuid); newCounter.setCount(1); nCounter.add(newCounter); } } if (abortCount) return; notebookSignal.countsChanged.emit(nCounter); logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()"); } /* private void countTagResults() { logger.log(logger.EXTREME, "Entering ListManager.countTagResults"); List<TagCounter> counter = new ArrayList<TagCounter>(); List<Tag> allTags = conn.getTagTable().getAll(); if (abortCount) return; if (allTags == null) return; for (int k=0; k<allTags.size() && keepRunning; k++) { TagCounter newCounter = new TagCounter(); newCounter.setGuid(allTags.get(k).getGuid()); newCounter.setCount(0); counter.add(newCounter); } if (type == TAG_ALL) { List<Pair<String, Integer>> tagCounts = conn.getNoteTable().noteTagsTable.getTagCounts(); if (abortCount) return; for (int i=0; tagCounts != null && i<tagCounts.size(); i++) { if (abortCount) return; for (int j=0; j<counter.size(); j++) { if (abortCount) return; if (tagCounts.get(i).getFirst().equals(counter.get(j).getGuid())) { if (abortCount) return; counter.get(j).setCount(tagCounts.get(i).getSecond()); j=counter.size(); } } } if (abortCount) return; tagSignal.countsChanged.emit(counter); return; } if (abortCount) return; List<cx.fbn.nevernote.sql.NoteTagsRecord> tags = conn.getNoteTable().noteTagsTable.getAllNoteTags(); for (int i=noteIndex.size()-1; i>=0; i--) { if (abortCount) return; String note = noteIndex.get(i); for (int x=0; tags!= null && x<tags.size() && keepRunning; x++) { if (abortCount) return; String tag = tags.get(x).tagGuid; for (int j=0; j<counter.size() && keepRunning; j++) { if (abortCount) return; if (counter.get(j).getGuid().equals(tag) && note.equals(tags.get(x).noteGuid)) { int c = counter.get(j).getCount()+1; counter.get(j).setCount(c); } } } } if (abortCount) return; tagSignal.countsChanged.emit(counter); logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()"); } */ private void countTagResults() { logger.log(logger.EXTREME, "Entering ListManager.countTagResults"); if (abortCount) return; List<TagCounter> tCounter = new ArrayList<TagCounter>(); for (int i=0; i<records.size(); i++) { if (abortCount) return; // Loop through the list of tags so we can count them Vector<String> tags = records.get(i).tags; for (int z=0; z<tags.size(); z++) { boolean found = false; for (int j=0; j<tCounter.size(); j++) { if (abortCount) return; if (tCounter.get(j).getGuid().equals(tags.get(z))) { tCounter.get(j).setCount(tCounter.get(j).getCount()+1); found = true; j=tCounter.size(); } } if (!found) { TagCounter newCounter = new TagCounter(); newCounter.setGuid(tags.get(z)); newCounter.setCount(1); tCounter.add(newCounter); } } } if (abortCount) return; tagSignal.countsChanged.emit(tCounter); logger.log(logger.EXTREME, "Leaving ListManager.countTagResults"); } private void countTrashResults() { logger.log(logger.EXTREME, "Entering CounterRunner.countTrashResults()"); if (abortCount) return; int tCounter = 0; for (int i=0; i<records.size(); i++) { if (abortCount) return; if (!records.get(i).active) tCounter++; } if (abortCount) return; trashSignal.countChanged.emit(tCounter); logger.log(logger.EXTREME, "Leaving CounterRunner.countTrashResults()"); } }