#include "ServerRepositoryDataUpdateProcess.h"
#include <stdio.h>
#include <sys/stat.h>
#include <time.h>
#include <AutoDeleter.h>
#include <Catalog.h>
#include <FileIO.h>
#include <Url.h>
#include "DumpExportRepositoryJsonListener.h"
#include "DumpExportRepositoryModel.h"
#include "Logger.h"
#include "PackageInfo.h"
#include "ServerSettings.h"
#include "StorageUtils.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "ServerRepositoryDataUpdateProcess"
class DepotMatchingRepositoryListener : public DumpExportRepositoryListener {
public:
DepotMatchingRepositoryListener(Model* model, Stoppable* stoppable);
virtual ~DepotMatchingRepositoryListener();
virtual bool Handle(DumpExportRepositoryRef item);
void Handle(DumpExportRepositoryRef repository,
DumpExportRepositorySourceRef repositorySource);
void Handle(const BString& identifier,
DumpExportRepositoryRef repository,
DumpExportRepositorySourceRef repositorySource);
virtual void Complete();
private:
void _SetupRepositoryData(
DepotInfoRef& depot,
DumpExportRepositoryRef repository,
DumpExportRepositorySourceRef repositorySource);
private:
Model* fModel;
Stoppable* fStoppable;
std::vector<DepotInfoRef>
fDepots;
};
DepotMatchingRepositoryListener::DepotMatchingRepositoryListener(Model* model, Stoppable* stoppable)
:
fModel(model),
fStoppable(stoppable),
fDepots()
{
}
DepotMatchingRepositoryListener::~DepotMatchingRepositoryListener()
{
}
void
DepotMatchingRepositoryListener::_SetupRepositoryData(DepotInfoRef& depot,
DumpExportRepositoryRef repository, DumpExportRepositorySourceRef repositorySource)
{
BString repositoryCode = repository->Code();
BString repositorySourceCode = repositorySource->Code();
DepotInfoBuilder depotBuilder(depot);
depotBuilder.WithWebAppRepositoryCode(repositoryCode);
depotBuilder.WithWebAppRepositorySourceCode(repositorySourceCode);
DepotInfoRef depotInfo = depotBuilder.BuildRef();
fDepots.push_back(depotInfo);
if (Logger::IsDebugEnabled()) {
HDDEBUG("[DepotMatchingRepositoryListener] associated depot [%s] (%s) "
"with server repository source [%s] (%s)",
depot->Name().String(), depot->Identifier().String(), repositorySourceCode.String(),
repositorySource->Identifier().String());
} else {
HDINFO("[DepotMatchingRepositoryListener] associated depot [%s] with "
"server repository source [%s]",
depot->Name().String(), repositorySourceCode.String());
}
}
void
DepotMatchingRepositoryListener::Handle(const BString& identifier,
DumpExportRepositoryRef repository, DumpExportRepositorySourceRef repositorySource)
{
if (!identifier.IsEmpty()) {
DepotInfoRef depotForIdentifier = fModel->DepotForIdentifier(identifier);
if (depotForIdentifier.IsSet())
_SetupRepositoryData(depotForIdentifier, repository, repositorySource);
}
}
void
DepotMatchingRepositoryListener::Handle(DumpExportRepositoryRef repository,
DumpExportRepositorySourceRef repositorySource)
{
if (repositorySource->IsSetIdentifier())
Handle(repositorySource->Identifier(), repository, repositorySource);
for (int32 i = 0; i < repositorySource->CountExtraIdentifiers(); i++)
Handle(repositorySource->ExtraIdentifiersItemAt(i), repository, repositorySource);
}
bool
DepotMatchingRepositoryListener::Handle(DumpExportRepositoryRef repository)
{
int32 i;
for (i = 0; i < repository->CountRepositorySources(); i++)
Handle(repository, repository->RepositorySourcesItemAt(i));
return !fStoppable->WasStopped();
}
void
DepotMatchingRepositoryListener::Complete()
{
fModel->SetDepots(fDepots);
}
ServerRepositoryDataUpdateProcess::ServerRepositoryDataUpdateProcess(Model* model,
uint32 serverProcessOptions)
:
AbstractSingleFileServerProcess(serverProcessOptions),
fModel(model)
{
}
ServerRepositoryDataUpdateProcess::~ServerRepositoryDataUpdateProcess()
{
}
const char*
ServerRepositoryDataUpdateProcess::Name() const
{
return "ServerRepositoryDataUpdateProcess";
}
const char*
ServerRepositoryDataUpdateProcess::Description() const
{
return B_TRANSLATE("Synchronizing meta-data about repositories");
}
BString
ServerRepositoryDataUpdateProcess::UrlPathComponent()
{
BString result;
result.SetToFormat("/__repository/all-%s.json.gz", fModel->PreferredLanguage()->ID());
return result;
}
status_t
ServerRepositoryDataUpdateProcess::GetLocalPath(BPath& path) const
{
return StorageUtils::DumpExportRepositoryDataPath(path, fModel->PreferredLanguage());
}
status_t
ServerRepositoryDataUpdateProcess::ProcessLocalData()
{
DepotMatchingRepositoryListener* itemListener
= new DepotMatchingRepositoryListener(fModel, this);
ObjectDeleter<DepotMatchingRepositoryListener> itemListenerDeleter(itemListener);
BulkContainerDumpExportRepositoryJsonListener* listener
= new BulkContainerDumpExportRepositoryJsonListener(itemListener);
ObjectDeleter<BulkContainerDumpExportRepositoryJsonListener> listenerDeleter(listener);
BPath localPath;
status_t result = GetLocalPath(localPath);
if (result != B_OK)
return result;
result = ParseJsonFromFileWithListener(listener, localPath);
if (result != B_OK)
return result;
return listener->ErrorStatus();
}
status_t
ServerRepositoryDataUpdateProcess::GetStandardMetaDataPath(BPath& path) const
{
return GetLocalPath(path);
}
void
ServerRepositoryDataUpdateProcess::GetStandardMetaDataJsonPath(BString& jsonPath) const
{
jsonPath.SetTo("$.info");
}