This source file includes following definitions.
- CreateSkeletonEntryForUrl
- RunArticleAvailableCallback
- distiller_factory_
- GetSyncableService
- AddToList
- GetEntries
- RemoveEntry
- ViewEntry
- ViewUrl
- GetOrCreateTaskTrackerForUrl
- GetTaskTrackerForEntry
- GetOrCreateTaskTrackerForEntry
- CreateTaskTracker
- CancelTask
- AddDistilledPageToList
- AddObserver
- RemoveObserver
#include "components/dom_distiller/core/dom_distiller_service.h"
#include "base/guid.h"
#include "base/message_loop/message_loop.h"
#include "components/dom_distiller/core/dom_distiller_store.h"
#include "components/dom_distiller/core/proto/distilled_article.pb.h"
#include "components/dom_distiller/core/task_tracker.h"
#include "url/gurl.h"
namespace dom_distiller {
namespace {
ArticleEntry CreateSkeletonEntryForUrl(const GURL& url) {
ArticleEntry skeleton;
skeleton.set_entry_id(base::GenerateGUID());
ArticleEntryPage* page = skeleton.add_pages();
page->set_url(url.spec());
DCHECK(IsEntryValid(skeleton));
return skeleton;
}
void RunArticleAvailableCallback(
const DomDistillerService::ArticleAvailableCallback& article_cb,
const ArticleEntry& entry,
const DistilledArticleProto* article_proto,
bool distillation_succeeded) {
article_cb.Run(distillation_succeeded);
}
}
DomDistillerService::DomDistillerService(
scoped_ptr<DomDistillerStoreInterface> store,
scoped_ptr<DistillerFactory> distiller_factory)
: store_(store.Pass()), distiller_factory_(distiller_factory.Pass()) {}
DomDistillerService::~DomDistillerService() {}
syncer::SyncableService* DomDistillerService::GetSyncableService() const {
return store_->GetSyncableService();
}
const std::string DomDistillerService::AddToList(
const GURL& url,
const ArticleAvailableCallback& article_cb) {
ArticleEntry entry;
const bool is_already_added = store_->GetEntryByUrl(url, &entry);
TaskTracker* task_tracker;
if (is_already_added) {
task_tracker = GetTaskTrackerForEntry(entry);
if (task_tracker == NULL) {
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(article_cb, true));
return entry.entry_id();
}
} else {
task_tracker = GetOrCreateTaskTrackerForUrl(url);
}
if (!article_cb.is_null()) {
task_tracker->AddSaveCallback(
base::Bind(&RunArticleAvailableCallback, article_cb));
}
if (!is_already_added) {
task_tracker->AddSaveCallback(base::Bind(
&DomDistillerService::AddDistilledPageToList, base::Unretained(this)));
task_tracker->StartDistiller(distiller_factory_.get());
}
return task_tracker->GetEntryId();
}
std::vector<ArticleEntry> DomDistillerService::GetEntries() const {
return store_->GetEntries();
}
scoped_ptr<ArticleEntry> DomDistillerService::RemoveEntry(
const std::string& entry_id) {
scoped_ptr<ArticleEntry> entry(new ArticleEntry);
entry->set_entry_id(entry_id);
TaskTracker* task_tracker = GetTaskTrackerForEntry(*entry);
if (task_tracker != NULL) {
task_tracker->CancelSaveCallbacks();
}
if (!store_->GetEntryById(entry_id, entry.get())) {
return scoped_ptr<ArticleEntry>();
}
if (store_->RemoveEntry(*entry)) {
return entry.Pass();
}
return scoped_ptr<ArticleEntry>();
}
scoped_ptr<ViewerHandle> DomDistillerService::ViewEntry(
ViewRequestDelegate* delegate,
const std::string& entry_id) {
ArticleEntry entry;
if (!store_->GetEntryById(entry_id, &entry)) {
return scoped_ptr<ViewerHandle>();
}
TaskTracker* task_tracker = GetOrCreateTaskTrackerForEntry(entry);
scoped_ptr<ViewerHandle> viewer_handle = task_tracker->AddViewer(delegate);
task_tracker->StartDistiller(distiller_factory_.get());
return viewer_handle.Pass();
}
scoped_ptr<ViewerHandle> DomDistillerService::ViewUrl(
ViewRequestDelegate* delegate,
const GURL& url) {
if (!url.is_valid()) {
return scoped_ptr<ViewerHandle>();
}
TaskTracker* task_tracker = GetOrCreateTaskTrackerForUrl(url);
scoped_ptr<ViewerHandle> viewer_handle = task_tracker->AddViewer(delegate);
task_tracker->StartDistiller(distiller_factory_.get());
return viewer_handle.Pass();
}
TaskTracker* DomDistillerService::GetOrCreateTaskTrackerForUrl(
const GURL& url) {
ArticleEntry entry;
if (store_->GetEntryByUrl(url, &entry)) {
return GetOrCreateTaskTrackerForEntry(entry);
}
for (TaskList::iterator it = tasks_.begin(); it != tasks_.end(); ++it) {
if ((*it)->HasUrl(url)) {
return *it;
}
}
ArticleEntry skeleton_entry = CreateSkeletonEntryForUrl(url);
TaskTracker* task_tracker = CreateTaskTracker(skeleton_entry);
return task_tracker;
}
TaskTracker* DomDistillerService::GetTaskTrackerForEntry(
const ArticleEntry& entry) const {
const std::string& entry_id = entry.entry_id();
for (TaskList::const_iterator it = tasks_.begin(); it != tasks_.end(); ++it) {
if ((*it)->HasEntryId(entry_id)) {
return *it;
}
}
return NULL;
}
TaskTracker* DomDistillerService::GetOrCreateTaskTrackerForEntry(
const ArticleEntry& entry) {
TaskTracker* task_tracker = GetTaskTrackerForEntry(entry);
if (task_tracker == NULL) {
task_tracker = CreateTaskTracker(entry);
}
return task_tracker;
}
TaskTracker* DomDistillerService::CreateTaskTracker(const ArticleEntry& entry) {
TaskTracker::CancelCallback cancel_callback =
base::Bind(&DomDistillerService::CancelTask, base::Unretained(this));
TaskTracker* tracker = new TaskTracker(entry, cancel_callback);
tasks_.push_back(tracker);
return tracker;
}
void DomDistillerService::CancelTask(TaskTracker* task) {
TaskList::iterator it = std::find(tasks_.begin(), tasks_.end(), task);
if (it != tasks_.end()) {
tasks_.weak_erase(it);
base::MessageLoop::current()->DeleteSoon(FROM_HERE, task);
}
}
void DomDistillerService::AddDistilledPageToList(
const ArticleEntry& entry,
const DistilledArticleProto* article_proto,
bool distillation_succeeded) {
DCHECK(IsEntryValid(entry));
if (distillation_succeeded) {
DCHECK(article_proto);
DCHECK_GT(article_proto->pages_size(), 0);
store_->AddEntry(entry);
DCHECK_EQ(article_proto->pages_size(), entry.pages_size());
}
}
void DomDistillerService::AddObserver(DomDistillerObserver* observer) {
DCHECK(observer);
store_->AddObserver(observer);
}
void DomDistillerService::RemoveObserver(DomDistillerObserver* observer) {
DCHECK(observer);
store_->RemoveObserver(observer);
}
}