Pull class AppMetaMimeCreator out of CreateAppMetaMimeThread

Instead of using a BMimeType to set the MIME type properties, it
operates directly on the Database object, though.
This commit is contained in:
Ingo Weinhold
2013-05-08 01:08:16 +02:00
parent b94857b322
commit b6a89f410e
8 changed files with 343 additions and 145 deletions
-1
View File
@@ -158,7 +158,6 @@ class BMimeType {
// for testing only
friend class BAppFileInfo;
friend class BPrivate::Storage::Mime::CreateAppMetaMimeThread;
virtual void _ReservedMimeType1();
virtual void _ReservedMimeType2();
@@ -0,0 +1,62 @@
/*
* Copyright 2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold <[email protected]>
*/
#ifndef _MIME_APP_META_MIME_CREATOR_H
#define _MIME_APP_META_MIME_CREATOR_H
#include <SupportDefs.h>
#include <MergedDirectory.h>
struct entry_ref;
namespace BPrivate {
namespace Storage {
namespace Mime {
class Database;
class AppMetaMimeCreator {
public:
class DatabaseLocker;
public:
AppMetaMimeCreator(Database* database,
DatabaseLocker* databaseLocker,
int32 force);
~AppMetaMimeCreator();
status_t Do(const entry_ref& entry, bool* _entryIsDir);
private:
Database* fDatabase;
DatabaseLocker* fDatabaseLocker;
int32 fForce;
};
class AppMetaMimeCreator::DatabaseLocker {
public:
virtual ~DatabaseLocker();
virtual bool Lock() = 0;
virtual void Unlock() = 0;
};
} // namespace Mime
} // namespace Storage
} // namespace BPrivate
#endif // _MIME_APP_META_MIME_CREATOR_H
@@ -0,0 +1,214 @@
/*
* Copyright 2002-2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Axel Dörfler, [email protected]
* Ingo Weinhold, [email protected]
*/
#include <mime/AppMetaMimeCreator.h>
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <File.h>
#include <fs_attr.h>
#include <Message.h>
#include <MimeType.h>
#include <String.h>
#include <AutoLocker.h>
#include <mime/Database.h>
#include <mime/database_support.h>
#include <mime/DatabaseLocation.h>
namespace BPrivate {
namespace Storage {
namespace Mime {
// #pragma mark - AppMetaMimeCreator
AppMetaMimeCreator::AppMetaMimeCreator(Database* database,
DatabaseLocker* databaseLocker, int32 force)
:
fDatabase(database),
fDatabaseLocker(databaseLocker),
fForce(force)
{
}
AppMetaMimeCreator::~AppMetaMimeCreator()
{
}
status_t
AppMetaMimeCreator::Do(const entry_ref& entry, bool* _entryIsDir)
{
BFile file;
status_t status = file.SetTo(&entry, B_READ_ONLY | O_NOTRAVERSE);
if (status < B_OK)
return status;
bool isDir = file.IsDirectory();
if (_entryIsDir != NULL)
*_entryIsDir = isDir;
if (isDir || !file.IsFile())
return B_OK;
BAppFileInfo appInfo(&file);
status = appInfo.InitCheck();
if (status < B_OK)
return status;
// Read the app sig (which consequently keeps us from updating
// non-applications, since we get an error if the file has no
// app sig)
BString signature;
status = file.ReadAttrString("BEOS:APP_SIG", &signature);
if (status != B_OK)
return B_BAD_TYPE;
if (!BMimeType::IsValid(signature))
return B_BAD_TYPE;
InstallNotificationDeferrer _(fDatabase, signature.String());
if (!fDatabase->Location()->IsInstalled(signature)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
fDatabase->Install(signature);
}
BNode typeNode;
status = fDatabase->Location()->OpenType(signature, typeNode);
if (status != B_OK)
return status;
// Preferred App
attr_info info;
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetPreferredApp(signature, signature);
}
// Short Description (name of the application)
if (status == B_OK
&& (fForce
|| typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetShortDescription(signature, entry.name);
}
// App Hint
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK)) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetAppHint(signature, &entry);
}
// Vector Icon
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
uint8* data = NULL;
size_t size = 0;
if (appInfo.GetIcon(&data, &size) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIcon(signature, data, size);
free(data);
}
}
// Mini Icon
BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIcon(signature, &miniIcon, B_MINI_ICON);
}
}
// Large Icon
BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK
&& (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIcon(signature, &largeIcon, B_LARGE_ICON);
}
}
// Supported Types
bool setSupportedTypes = false;
BMessage supportedTypes;
if (status == B_OK
&& (fForce
|| typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
setSupportedTypes = true;
}
// defer notifications for supported types
const char* type;
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
fDatabase->DeferInstallNotification(type);
// set supported types
if (setSupportedTypes) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetSupportedTypes(signature, &supportedTypes, true);
}
// Icons for supported types
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK;
i++) {
// vector icon
uint8* data = NULL;
size_t size = 0;
if (status == B_OK
&& appInfo.GetIconForType(type, &data, &size) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIconForType(signature, type, data, size);
free(data);
}
// mini icon
if (status == B_OK
&& appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIconForType(signature, type, &miniIcon,
B_MINI_ICON);
}
// large icon
if (status == B_OK
&& appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK) {
AutoLocker<DatabaseLocker> databaseLocker(fDatabaseLocker);
status = fDatabase->SetIconForType(signature, type, &largeIcon,
B_LARGE_ICON);
}
}
// undefer notifications for supported types
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
fDatabase->UndeferInstallNotification(type);
return status;
}
// #pragma mark - DatabaseLocker
AppMetaMimeCreator::DatabaseLocker::~DatabaseLocker()
{
}
} // namespace Mime
} // namespace Storage
} // namespace BPrivate
+1
View File
@@ -10,6 +10,7 @@ UsePrivateHeaders app shared storage ;
#UsePublicHeaders [ FDirName add-ons registrar ] ;
StaticLibrary libstorage_kit_mime.a :
AppMetaMimeCreator.cpp
AssociatedTypes.cpp
Database.cpp
DatabaseDirectory.cpp
+27 -1
View File
@@ -21,6 +21,7 @@
#include <String.h>
#include <TypeConstants.h>
#include <mime/AppMetaMimeCreator.h>
#include <mime/database_support.h>
#include "CreateAppMetaMimeThread.h"
@@ -53,6 +54,30 @@ init_mime_sniffer_add_on_manager()
}
class MIMEManager::DatabaseLocker
: public BPrivate::Storage::Mime::AppMetaMimeCreator::DatabaseLocker {
public:
DatabaseLocker(MIMEManager* manager)
:
fManager(manager)
{
}
virtual bool Lock()
{
return fManager->Lock();
}
virtual void Unlock()
{
fManager->Unlock();
}
private:
MIMEManager* fManager;
};
/*! \brief Creates and initializes a MIMEManager.
*/
MIMEManager::MIMEManager()
@@ -60,6 +85,7 @@ MIMEManager::MIMEManager()
BLooper("main_mime"),
fDatabase(BPrivate::Storage::Mime::default_database_location(),
init_mime_sniffer_add_on_manager(), this),
fDatabaseLocker(new(std::nothrow) DatabaseLocker(this)),
fThreadManager()
{
AddHandler(&fThreadManager);
@@ -245,7 +271,7 @@ MIMEManager::MessageReceived(BMessage *message)
thread = new(nothrow) CreateAppMetaMimeThread(
synchronous ? "create_app_meta_mime (s)"
: "create_app_meta_mime (a)",
B_NORMAL_PRIORITY + 1, &fDatabase,
B_NORMAL_PRIORITY + 1, &fDatabase, fDatabaseLocker,
BMessenger(&fThreadManager), &root, recursive,
force, synchronous ? message : NULL);
break;
+6 -1
View File
@@ -22,11 +22,16 @@ private:
// Database::NotificationListener
virtual status_t Notify(BMessage* message, const BMessenger& target);
private:
class DatabaseLocker;
private:
void HandleSetParam(BMessage *message);
void HandleDeleteParam(BMessage *message);
private:
BPrivate::Storage::Mime::Database fDatabase;
DatabaseLocker* fDatabaseLocker;
RegistrarThreadManager fThreadManager;
BMessenger fManagerMessenger;
};
@@ -1,41 +1,31 @@
/*
* Copyright 2002-2006, Haiku.
* Copyright 2002-2013, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Axel Dörfler, axeld@pinc-software.de
* Ingo Weinhold, ingo_weinhold@gmx.de
*/
#include "CreateAppMetaMimeThread.h"
#include <stdio.h>
#include <stdlib.h>
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <fs_attr.h>
#include <MimeType.h>
#include <Node.h>
#include <Path.h>
#include <String.h>
#include <mime/Database.h>
#include <mime/database_support.h>
#include <mime/DatabaseLocation.h>
namespace BPrivate {
namespace Storage {
namespace Mime {
CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char *name,
int32 priority, Database *database, BMessenger managerMessenger,
const entry_ref *root, bool recursive, int32 force, BMessage *replyee)
: MimeUpdateThread(name, priority, database, managerMessenger, root,
recursive, force, replyee)
CreateAppMetaMimeThread::CreateAppMetaMimeThread(const char* name,
int32 priority, Database* database,
AppMetaMimeCreator::DatabaseLocker* databaseLocker,
BMessenger managerMessenger, const entry_ref* root, bool recursive,
int32 force, BMessage* replyee)
:
MimeUpdateThread(name, priority, database, managerMessenger, root,
recursive, force, replyee),
fCreator(database, databaseLocker, force)
{
}
@@ -46,124 +36,10 @@ CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
if (ref == NULL)
return B_BAD_VALUE;
BFile file;
status_t status = file.SetTo(ref, B_READ_ONLY | O_NOTRAVERSE);
if (status < B_OK)
return status;
bool isDir = file.IsDirectory();
if (_entryIsDir != NULL)
*_entryIsDir = isDir;
if (isDir || !file.IsFile())
return B_OK;
BAppFileInfo appInfo(&file);
status = appInfo.InitCheck();
if (status < B_OK)
return status;
// Read the app sig (which consequently keeps us from updating
// non-applications, since we get an error if the file has no
// app sig)
BString signature;
status = file.ReadAttrString("BEOS:APP_SIG", &signature);
if (status < B_OK)
return B_BAD_TYPE;
// Init our various objects
BMimeType mime;
status = mime.SetTo(signature.String());
if (status < B_OK)
return status;
InstallNotificationDeferrer _(fDatabase, signature.String());
if (!mime.IsInstalled())
mime.Install();
BNode typeNode;
status = fDatabase->Location()->OpenType(signature, typeNode);
if (status < B_OK)
return status;
// Preferred App
attr_info info;
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK))
status = mime.SetPreferredApp(signature.String());
// Short Description (name of the application)
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK))
status = mime.SetShortDescription(ref->name);
// App Hint
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
status = mime.SetAppHint(ref);
// Vector Icon
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
uint8* data = NULL;
size_t size = 0;
if (appInfo.GetIcon(&data, &size) == B_OK) {
status = mime.SetIcon(data, size);
free(data);
}
}
// Mini Icon
BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK)
status = mime.SetIcon(&miniIcon, B_MINI_ICON);
}
// Large Icon
BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK)
status = mime.SetIcon(&largeIcon, B_LARGE_ICON);
}
// Supported Types
bool setSupportedTypes = false;
BMessage supportedTypes;
if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
setSupportedTypes = true;
}
// defer notifications for supported types
const char* type;
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
fDatabase->DeferInstallNotification(type);
// set supported types
if (setSupportedTypes)
status = mime.SetSupportedTypes(&supportedTypes);
// Icons for supported types
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
// vector icon
uint8* data = NULL;
size_t size = 0;
if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
status = mime.SetIconForType(type, data, size);
free(data);
}
// mini icon
if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
// large icon
if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK)
status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON);
}
// undefer notifications for supported types
for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
fDatabase->UndeferInstallNotification(type);
return status;
return fCreator.Do(*ref, _entryIsDir);
}
} // namespace Mime
} // namespace Storage
} // namespace BPrivate
@@ -10,20 +10,35 @@
#ifndef _CREATE_APP_META_MIME_THREAD_H
#define _CREATE_APP_META_MIME_THREAD_H
#include <mime/AppMetaMimeCreator.h>
#include "MimeUpdateThread.h"
namespace BPrivate {
namespace Storage {
namespace Mime {
class CreateAppMetaMimeThread : public MimeUpdateThread {
public:
CreateAppMetaMimeThread(const char *name, int32 priority,
Database *database, BMessenger managerMessenger, const entry_ref *root,
bool recursive, int32 force, BMessage *replyee);
status_t DoMimeUpdate(const entry_ref *entry, bool *entryIsDir);
CreateAppMetaMimeThread(const char* name,
int32 priority, Database* database,
AppMetaMimeCreator::DatabaseLocker*
databaseLocker,
BMessenger managerMessenger,
const entry_ref* root, bool recursive,
int32 force, BMessage* replyee);
virtual status_t DoMimeUpdate(const entry_ref* entry,
bool* _entryIsDir);
private:
AppMetaMimeCreator fCreator;
};
} // namespace Mime
} // namespace Storage
} // namespace BPrivate