<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include "LocalDomainAccessStore.h"

#include <algorithm>
#include <iterator>

#include "AceValidator.h"
#include "joynr/Util.h"

namespace joynr
{
using namespace infrastructure::DacTypes;

INIT_LOGGER(LocalDomainAccessStore);

LocalDomainAccessStore::LocalDomainAccessStore() : persistenceFileName()
{
}

LocalDomainAccessStore::LocalDomainAccessStore(std::string fileName)
        : persistenceFileName(std::move(fileName))
{
    try {
        joynr::serializer::deserializeFromJson(
                *this, joynr::util::loadStringFromFile(persistenceFileName));
    } catch (const std::runtime_error& ex) {
        JOYNR_LOG_ERROR(logger, ex.what());
    } catch (const std::invalid_argument& ex) {
        JOYNR_LOG_ERROR(logger,
                        "Could not deserialize persisted access control entries from {}: {}",
                        persistenceFileName,
                        ex.what());
    }
}

std::set<std::pair<std::string, std::string>> LocalDomainAccessStore::
        getUniqueDomainInterfaceCombinations() const
{
    std::set<std::pair<std::string, std::string>> result;

    auto insertInResult = [&result](const auto& entry) {
        result.insert(std::make_pair(entry.getDomain(), entry.getInterfaceName()));
    };

    for (const auto& masterACE : masterTable) {
        insertInResult(masterACE);
    }

    for (const auto& mediatorACE : mediatorTable) {
        insertInResult(mediatorACE);
    }

    for (const auto& ownerACE : ownerTable) {
        insertInResult(ownerACE);
    }

    return result;
}

std::vector<DomainRoleEntry> LocalDomainAccessStore::getDomainRoles(const std::string& userId)
{
    JOYNR_LOG_TRACE(logger, "execute: entering getDomainRoleEntries with userId {}", userId);

    std::vector<DomainRoleEntry> domainRoles;
    boost::optional<DomainRoleEntry> masterDre = getDomainRole(userId, Role::MASTER);
    if (masterDre) {
        // add dre to resultset only if it defines role for some domain
        domainRoles.push_back(*masterDre);
    }

    boost::optional<DomainRoleEntry> ownerDre = getDomainRole(userId, Role::OWNER);
    if (ownerDre) {
        // add dre to resultset only if it defines role for some domain
        domainRoles.push_back(*ownerDre);
    }

    return domainRoles;
}

boost::optional<DomainRoleEntry> LocalDomainAccessStore::getDomainRole(const std::string& uid,
                                                                       Role::Enum role)
{
    return lookupOptional(domainRoleTable, uid, role);
}

bool LocalDomainAccessStore::updateDomainRole(const DomainRoleEntry& updatedEntry)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateDomainRoleEntry with uId {}", updatedEntry.getUid());

    return insertOrReplace(domainRoleTable, updatedEntry);
}

bool LocalDomainAccessStore::removeDomainRole(const std::string& userId, Role::Enum role)
{
    JOYNR_LOG_TRACE(logger, "execute: entering removeDomainRoleEntry with uId {}", userId);
    return removeFromTable(domainRoleTable, userId, role);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntries(
        const std::string& uid) const
{
    return getEqualRangeWithUidWildcard(masterTable, uid);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntries(
        const std::string& domain,
        const std::string& interfaceName) const
{
    return getEqualRange(
            masterTable.get<access_control::tags::DomainAndInterface>(), domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntries(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRangeWithUidWildcard(masterTable, uid, domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getEditableMasterAccessControlEntries(
        const std::string& userId)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering getEditableMasterAccessControlEntry with uId {}", userId);

    return getEditableAccessControlEntries(masterTable, userId, Role::MASTER);
}

boost::optional<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntry(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName,
        const std::string& operation)
{
    return lookupOptionalWithWildcard(masterTable, uid, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::updateMasterAccessControlEntry(
        const MasterAccessControlEntry& updatedMasterAce)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateMasterAce with uId {}", updatedMasterAce.getUid());

    return insertOrReplace(masterTable, updatedMasterAce);
}

bool LocalDomainAccessStore::removeMasterAccessControlEntry(const std::string& userId,
                                                            const std::string& domain,
                                                            const std::string& interfaceName,
                                                            const std::string& operation)
{
    return removeFromTable(masterTable, userId, domain, interfaceName, operation);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntries(
        const std::string& uid)
{
    return getEqualRangeWithUidWildcard(mediatorTable, uid);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntries(
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRange(
            mediatorTable.get<access_control::tags::DomainAndInterface>(), domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntries(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRangeWithUidWildcard(mediatorTable, uid, domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::
        getEditableMediatorAccessControlEntries(const std::string& userId)
{
    JOYNR_LOG_TRACE(logger, "execute: entering getEditableMediatorAces with uId {}", userId);

    // Get all the Mediator ACEs for the domains where the user is master
    return getEditableAccessControlEntries(mediatorTable, userId, Role::MASTER);
}

boost::optional<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntry(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName,
        const std::string& operation)
{
    return lookupOptionalWithWildcard(mediatorTable, uid, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::updateMediatorAccessControlEntry(
        const MasterAccessControlEntry& updatedMediatorAce)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateMediatorAce with uId {}", updatedMediatorAce.getUid());

    bool updateSuccess = false;

    boost::optional<MasterAccessControlEntry> masterAceOptional =
            getMasterAccessControlEntry(updatedMediatorAce.getUid(),
                                        updatedMediatorAce.getDomain(),
                                        updatedMediatorAce.getInterfaceName(),
                                        updatedMediatorAce.getOperation());
    AceValidator aceValidator(masterAceOptional,
                              boost::optional<MasterAccessControlEntry>(updatedMediatorAce),
                              boost::optional<OwnerAccessControlEntry>());

    if (aceValidator.isMediatorValid()) {
        // Add/update a mediator ACE
        updateSuccess = insertOrReplace(mediatorTable, updatedMediatorAce);
    }

    return updateSuccess;
}

bool LocalDomainAccessStore::removeMediatorAccessControlEntry(const std::string& userId,
                                                              const std::string& domain,
                                                              const std::string& interfaceName,
                                                              const std::string& operation)
{
    JOYNR_LOG_TRACE(logger,
                    "execute: entering removeMediatorAce with userId: {}, domain: {}, "
                    "interfaceName: {}, operation: {}",
                    userId,
                    domain,
                    interfaceName,
                    operation);
    return removeFromTable(mediatorTable, userId, domain, interfaceName, operation);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntries(
        const std::string& uid)
{
    return getEqualRangeWithUidWildcard(ownerTable, uid);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntries(
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRange(
            ownerTable.get<access_control::tags::DomainAndInterface>(), domain, interfaceName);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntries(
        const std::string& userId,
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRangeWithUidWildcard(ownerTable, userId, domain, interfaceName);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getEditableOwnerAccessControlEntries(
        const std::string& userId)
{
    JOYNR_LOG_TRACE(logger, "execute: entering getEditableOwnerAces with uId {}", userId);

    // Get all the Owner ACEs for the domains owned by the user
    return getEditableAccessControlEntries(ownerTable, userId, Role::OWNER);
}

boost::optional<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntry(
        const std::string& userId,
        const std::string& domain,
        const std::string& interfaceName,
        const std::string& operation)
{
    return lookupOptionalWithWildcard(ownerTable, userId, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::updateOwnerAccessControlEntry(
        const OwnerAccessControlEntry& updatedOwnerAce)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateOwnerAce with uId {}", updatedOwnerAce.getUid());

    bool updateSuccess = false;

    boost::optional<MasterAccessControlEntry> masterAceOptional =
            getMasterAccessControlEntry(updatedOwnerAce.getUid(),
                                        updatedOwnerAce.getDomain(),
                                        updatedOwnerAce.getInterfaceName(),
                                        updatedOwnerAce.getOperation());
    boost::optional<MasterAccessControlEntry> mediatorAceOptional =
            getMediatorAccessControlEntry(updatedOwnerAce.getUid(),
                                          updatedOwnerAce.getDomain(),
                                          updatedOwnerAce.getInterfaceName(),
                                          updatedOwnerAce.getOperation());
    AceValidator aceValidator(masterAceOptional,
                              mediatorAceOptional,
                              boost::optional<OwnerAccessControlEntry>(updatedOwnerAce));

    if (aceValidator.isOwnerValid()) {
        updateSuccess = insertOrReplace(ownerTable, updatedOwnerAce);
    }
    return updateSuccess;
}

bool LocalDomainAccessStore::removeOwnerAccessControlEntry(const std::string& userId,
                                                           const std::string& domain,
                                                           const std::string& interfaceName,
                                                           const std::string& operation)
{
    JOYNR_LOG_TRACE(logger,
                    "execute: entering removeOwnerAce with userId: {}, domain: {}, interface: {}, "
                    "operation: {}",
                    userId,
                    domain,
                    interfaceName,
                    operation);

    return removeFromTable(ownerTable, userId, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::onlyWildcardOperations(const std::string& userId,
                                                    const std::string& domain,
                                                    const std::string& interfaceName)
{
    return checkOnlyWildcardOperations(masterTable, userId, domain, interfaceName) &&
           checkOnlyWildcardOperations(mediatorTable, userId, domain, interfaceName) &&
           checkOnlyWildcardOperations(ownerTable, userId, domain, interfaceName);
}

void LocalDomainAccessStore::persistToFile() const
{
    if (persistenceFileName.empty()) {
        return;
    }
    try {
        joynr::util::saveStringToFile(
                persistenceFileName, joynr::serializer::serializeToJson(*this));
    } catch (const std::invalid_argument& ex) {
        JOYNR_LOG_ERROR(logger, "serializing to JSON failed: {}", ex.what());
    } catch (const std::runtime_error& ex) {
        JOYNR_LOG_ERROR(logger, ex.what());
    }
}

} // namespace joynr
<commit_msg>[C++] Check for empty string in constructor of LocalDomainAccessStore.<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include "LocalDomainAccessStore.h"

#include <algorithm>
#include <iterator>

#include "AceValidator.h"
#include "joynr/Util.h"

namespace joynr
{
using namespace infrastructure::DacTypes;

INIT_LOGGER(LocalDomainAccessStore);

LocalDomainAccessStore::LocalDomainAccessStore() : persistenceFileName()
{
}

LocalDomainAccessStore::LocalDomainAccessStore(std::string fileName)
{
    if (fileName.empty()) {
        return;
    }

    persistenceFileName = std::move(fileName);

    try {
        joynr::serializer::deserializeFromJson(
                *this, joynr::util::loadStringFromFile(persistenceFileName));
    } catch (const std::runtime_error& ex) {
        JOYNR_LOG_ERROR(logger, ex.what());
    } catch (const std::invalid_argument& ex) {
        JOYNR_LOG_ERROR(logger,
                        "Could not deserialize persisted access control entries from {}: {}",
                        persistenceFileName,
                        ex.what());
    }
}

std::set<std::pair<std::string, std::string>> LocalDomainAccessStore::
        getUniqueDomainInterfaceCombinations() const
{
    std::set<std::pair<std::string, std::string>> result;

    auto insertInResult = [&result](const auto& entry) {
        result.insert(std::make_pair(entry.getDomain(), entry.getInterfaceName()));
    };

    for (const auto& masterACE : masterTable) {
        insertInResult(masterACE);
    }

    for (const auto& mediatorACE : mediatorTable) {
        insertInResult(mediatorACE);
    }

    for (const auto& ownerACE : ownerTable) {
        insertInResult(ownerACE);
    }

    return result;
}

std::vector<DomainRoleEntry> LocalDomainAccessStore::getDomainRoles(const std::string& userId)
{
    JOYNR_LOG_TRACE(logger, "execute: entering getDomainRoleEntries with userId {}", userId);

    std::vector<DomainRoleEntry> domainRoles;
    boost::optional<DomainRoleEntry> masterDre = getDomainRole(userId, Role::MASTER);
    if (masterDre) {
        // add dre to resultset only if it defines role for some domain
        domainRoles.push_back(*masterDre);
    }

    boost::optional<DomainRoleEntry> ownerDre = getDomainRole(userId, Role::OWNER);
    if (ownerDre) {
        // add dre to resultset only if it defines role for some domain
        domainRoles.push_back(*ownerDre);
    }

    return domainRoles;
}

boost::optional<DomainRoleEntry> LocalDomainAccessStore::getDomainRole(const std::string& uid,
                                                                       Role::Enum role)
{
    return lookupOptional(domainRoleTable, uid, role);
}

bool LocalDomainAccessStore::updateDomainRole(const DomainRoleEntry& updatedEntry)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateDomainRoleEntry with uId {}", updatedEntry.getUid());

    return insertOrReplace(domainRoleTable, updatedEntry);
}

bool LocalDomainAccessStore::removeDomainRole(const std::string& userId, Role::Enum role)
{
    JOYNR_LOG_TRACE(logger, "execute: entering removeDomainRoleEntry with uId {}", userId);
    return removeFromTable(domainRoleTable, userId, role);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntries(
        const std::string& uid) const
{
    return getEqualRangeWithUidWildcard(masterTable, uid);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntries(
        const std::string& domain,
        const std::string& interfaceName) const
{
    return getEqualRange(
            masterTable.get<access_control::tags::DomainAndInterface>(), domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntries(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRangeWithUidWildcard(masterTable, uid, domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getEditableMasterAccessControlEntries(
        const std::string& userId)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering getEditableMasterAccessControlEntry with uId {}", userId);

    return getEditableAccessControlEntries(masterTable, userId, Role::MASTER);
}

boost::optional<MasterAccessControlEntry> LocalDomainAccessStore::getMasterAccessControlEntry(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName,
        const std::string& operation)
{
    return lookupOptionalWithWildcard(masterTable, uid, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::updateMasterAccessControlEntry(
        const MasterAccessControlEntry& updatedMasterAce)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateMasterAce with uId {}", updatedMasterAce.getUid());

    return insertOrReplace(masterTable, updatedMasterAce);
}

bool LocalDomainAccessStore::removeMasterAccessControlEntry(const std::string& userId,
                                                            const std::string& domain,
                                                            const std::string& interfaceName,
                                                            const std::string& operation)
{
    return removeFromTable(masterTable, userId, domain, interfaceName, operation);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntries(
        const std::string& uid)
{
    return getEqualRangeWithUidWildcard(mediatorTable, uid);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntries(
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRange(
            mediatorTable.get<access_control::tags::DomainAndInterface>(), domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntries(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRangeWithUidWildcard(mediatorTable, uid, domain, interfaceName);
}

std::vector<MasterAccessControlEntry> LocalDomainAccessStore::
        getEditableMediatorAccessControlEntries(const std::string& userId)
{
    JOYNR_LOG_TRACE(logger, "execute: entering getEditableMediatorAces with uId {}", userId);

    // Get all the Mediator ACEs for the domains where the user is master
    return getEditableAccessControlEntries(mediatorTable, userId, Role::MASTER);
}

boost::optional<MasterAccessControlEntry> LocalDomainAccessStore::getMediatorAccessControlEntry(
        const std::string& uid,
        const std::string& domain,
        const std::string& interfaceName,
        const std::string& operation)
{
    return lookupOptionalWithWildcard(mediatorTable, uid, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::updateMediatorAccessControlEntry(
        const MasterAccessControlEntry& updatedMediatorAce)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateMediatorAce with uId {}", updatedMediatorAce.getUid());

    bool updateSuccess = false;

    boost::optional<MasterAccessControlEntry> masterAceOptional =
            getMasterAccessControlEntry(updatedMediatorAce.getUid(),
                                        updatedMediatorAce.getDomain(),
                                        updatedMediatorAce.getInterfaceName(),
                                        updatedMediatorAce.getOperation());
    AceValidator aceValidator(masterAceOptional,
                              boost::optional<MasterAccessControlEntry>(updatedMediatorAce),
                              boost::optional<OwnerAccessControlEntry>());

    if (aceValidator.isMediatorValid()) {
        // Add/update a mediator ACE
        updateSuccess = insertOrReplace(mediatorTable, updatedMediatorAce);
    }

    return updateSuccess;
}

bool LocalDomainAccessStore::removeMediatorAccessControlEntry(const std::string& userId,
                                                              const std::string& domain,
                                                              const std::string& interfaceName,
                                                              const std::string& operation)
{
    JOYNR_LOG_TRACE(logger,
                    "execute: entering removeMediatorAce with userId: {}, domain: {}, "
                    "interfaceName: {}, operation: {}",
                    userId,
                    domain,
                    interfaceName,
                    operation);
    return removeFromTable(mediatorTable, userId, domain, interfaceName, operation);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntries(
        const std::string& uid)
{
    return getEqualRangeWithUidWildcard(ownerTable, uid);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntries(
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRange(
            ownerTable.get<access_control::tags::DomainAndInterface>(), domain, interfaceName);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntries(
        const std::string& userId,
        const std::string& domain,
        const std::string& interfaceName)
{
    return getEqualRangeWithUidWildcard(ownerTable, userId, domain, interfaceName);
}

std::vector<OwnerAccessControlEntry> LocalDomainAccessStore::getEditableOwnerAccessControlEntries(
        const std::string& userId)
{
    JOYNR_LOG_TRACE(logger, "execute: entering getEditableOwnerAces with uId {}", userId);

    // Get all the Owner ACEs for the domains owned by the user
    return getEditableAccessControlEntries(ownerTable, userId, Role::OWNER);
}

boost::optional<OwnerAccessControlEntry> LocalDomainAccessStore::getOwnerAccessControlEntry(
        const std::string& userId,
        const std::string& domain,
        const std::string& interfaceName,
        const std::string& operation)
{
    return lookupOptionalWithWildcard(ownerTable, userId, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::updateOwnerAccessControlEntry(
        const OwnerAccessControlEntry& updatedOwnerAce)
{
    JOYNR_LOG_TRACE(
            logger, "execute: entering updateOwnerAce with uId {}", updatedOwnerAce.getUid());

    bool updateSuccess = false;

    boost::optional<MasterAccessControlEntry> masterAceOptional =
            getMasterAccessControlEntry(updatedOwnerAce.getUid(),
                                        updatedOwnerAce.getDomain(),
                                        updatedOwnerAce.getInterfaceName(),
                                        updatedOwnerAce.getOperation());
    boost::optional<MasterAccessControlEntry> mediatorAceOptional =
            getMediatorAccessControlEntry(updatedOwnerAce.getUid(),
                                          updatedOwnerAce.getDomain(),
                                          updatedOwnerAce.getInterfaceName(),
                                          updatedOwnerAce.getOperation());
    AceValidator aceValidator(masterAceOptional,
                              mediatorAceOptional,
                              boost::optional<OwnerAccessControlEntry>(updatedOwnerAce));

    if (aceValidator.isOwnerValid()) {
        updateSuccess = insertOrReplace(ownerTable, updatedOwnerAce);
    }
    return updateSuccess;
}

bool LocalDomainAccessStore::removeOwnerAccessControlEntry(const std::string& userId,
                                                           const std::string& domain,
                                                           const std::string& interfaceName,
                                                           const std::string& operation)
{
    JOYNR_LOG_TRACE(logger,
                    "execute: entering removeOwnerAce with userId: {}, domain: {}, interface: {}, "
                    "operation: {}",
                    userId,
                    domain,
                    interfaceName,
                    operation);

    return removeFromTable(ownerTable, userId, domain, interfaceName, operation);
}

bool LocalDomainAccessStore::onlyWildcardOperations(const std::string& userId,
                                                    const std::string& domain,
                                                    const std::string& interfaceName)
{
    return checkOnlyWildcardOperations(masterTable, userId, domain, interfaceName) &&
           checkOnlyWildcardOperations(mediatorTable, userId, domain, interfaceName) &&
           checkOnlyWildcardOperations(ownerTable, userId, domain, interfaceName);
}

void LocalDomainAccessStore::persistToFile() const
{
    if (persistenceFileName.empty()) {
        return;
    }
    try {
        joynr::util::saveStringToFile(
                persistenceFileName, joynr::serializer::serializeToJson(*this));
    } catch (const std::invalid_argument& ex) {
        JOYNR_LOG_ERROR(logger, "serializing to JSON failed: {}", ex.what());
    } catch (const std::runtime_error& ex) {
        JOYNR_LOG_ERROR(logger, ex.what());
    }
}

} // namespace joynr
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "RhoLogConf.h"
#include "RhoLogCat.h"
#include "RhoLogSink.h"
#include "common/RhoFile.h"
#include "common/RhoFilePath.h"
#include "common/RhoConf.h"
#include "common/Tokenizer.h"

#ifndef RHO_NO_RUBY
#include "ruby/ext/rho/rhoruby.h"
#endif //RHO_NO_RUBY

namespace rho{
common::CMutex LogSettings::m_FlushLock;
common::CMutex LogSettings::m_CatLock;

LogSettings g_LogSettings;

LogSettings::LogSettings(){
    m_nMinSeverity = 0;
    m_bLogToOutput = true;
    m_bLogToFile = false;
    m_bLogToSocket = false;

    m_nMaxLogFileSize = 0;
    m_bLogPrefix = true;

    m_strLogHost = "PPP_PEER";

    m_pFileSink = new CLogFileSink(*this);
    m_pOutputSink = new CLogOutputSink(*this);
    m_pLogViewSink = NULL;
	m_pSocketSink = NULL;
}

LogSettings::~LogSettings(){
    delete m_pFileSink;
    delete m_pOutputSink;
    delete m_pSocketSink;
}

void LogSettings::setLogPort(const char* szLogPort)
{
	setLogToSocket(true);

	m_strLogPort = rho::String(szLogPort);

	delete m_pSocketSink;
    m_pSocketSink = new CLogSocketSink(*this);
}

void LogSettings::getLogTextW(StringW& strTextW)
{
    boolean bOldSaveToFile = isLogToFile();
    setLogToFile(false);

    common::CRhoFile oFile;
    if ( oFile.open( getLogFilePath().c_str(), common::CRhoFile::OpenReadOnly) )
        oFile.readStringW(strTextW);

    setLogToFile(bOldSaveToFile);
}

void LogSettings::getLogText(String& strText)
{
    boolean bOldSaveToFile = isLogToFile();
    setLogToFile(false);

    common::CRhoFile oFile;
    if ( oFile.open( getLogFilePath().c_str(), common::CRhoFile::OpenReadOnly) )
        oFile.readString(strText);

    setLogToFile(bOldSaveToFile);
}

int LogSettings::getLogTextPos()
{
    return m_pFileSink ? m_pFileSink->getCurPos() : -1;
}

void LogSettings::saveToFile(){
    RHOCONF().setInt("MinSeverity", getMinSeverity(), true );
    RHOCONF().setBool("LogToOutput", isLogToOutput(), true );
    RHOCONF().setBool("LogToFile", isLogToFile(), true );
#if !defined(OS_MACOSX)
    RHOCONF().setString("LogFilePath", getLogFilePath(), true );
#endif
    RHOCONF().setInt("MaxLogFileSize", getMaxLogFileSize(), true );
    RHOCONF().setString("LogCategories", getEnabledCategories(), true );
    RHOCONF().setString("ExcludeLogCategories", getDisabledCategories(), true );
}

void LogSettings::loadFromConf(rho::common::RhoSettings& oRhoConf)
{
    if ( oRhoConf.isExist( "MinSeverity" ) )
        setMinSeverity( oRhoConf.getInt("MinSeverity") );
    if ( oRhoConf.isExist( "LogToOutput") )
        setLogToOutput( oRhoConf.getBool("LogToOutput") );
    if ( oRhoConf.isExist( "LogToFile") )
        setLogToFile( oRhoConf.getBool("LogToFile"));
    if ( oRhoConf.isExist( "LogFilePath") )
        setLogFilePath( oRhoConf.getString("LogFilePath").c_str() );
    if ( oRhoConf.isExist( "MaxLogFileSize") )
        setMaxLogFileSize( oRhoConf.getInt("MaxLogFileSize") );
    if ( oRhoConf.isExist( "LogCategories") )
        setEnabledCategories( oRhoConf.getString("LogCategories").c_str() );
    if (oRhoConf.isExist( "ExcludeLogCategories") )
        setDisabledCategories( oRhoConf.getString("ExcludeLogCategories").c_str() );
	if ( oRhoConf.isExist( "LogToSocket") )
		setLogToSocket( oRhoConf.getBool("LogToSocket") );
	if ( oRhoConf.isExist( "log_exclude_filter") )
        setExcludeFilter( oRhoConf.getString("log_exclude_filter") );
}

void LogSettings::setLogFilePath(const char* szLogFilePath){
    if ( m_strLogFilePath.compare(szLogFilePath) != 0 ){
        common::CMutexLock oLock(m_FlushLock);

        m_strLogFilePath = szLogFilePath;

        if ( m_pFileSink ){
            delete m_pFileSink;
            m_pFileSink = new CLogFileSink(*this);
        }
    }
}

void LogSettings::clearLog(){
    common::CMutexLock oLock(m_FlushLock);

    if ( m_pFileSink ){
        m_pFileSink->clear();
    }

}

void LogSettings::sinkLogMessage( String& strMsg ){
    common::CMutexLock oLock(m_FlushLock);

    if ( isLogToFile() )
        m_pFileSink->writeLogMessage(strMsg);

    if (m_pLogViewSink)
        m_pLogViewSink->writeLogMessage(strMsg);

    //Should be at the end
    if ( isLogToOutput() )
        m_pOutputSink->writeLogMessage(strMsg);

    if ( isLogToSocket() )
        m_pSocketSink->writeLogMessage(strMsg);
}

bool LogSettings::isCategoryEnabled(const LogCategory& cat)const{
    //TODO: Optimize categories search : add map
    common::CMutexLock oLock(m_CatLock);

    if ( m_strDisabledCategories.length() > 0 && strstr(m_strDisabledCategories.c_str(), cat.getName().c_str() ) != 0 )
        return false;

    if ( m_strEnabledCategories.length() == 0 )
        return false;

    return strcmp(m_strEnabledCategories.c_str(),"*") == 0 || strstr(m_strEnabledCategories.c_str(), cat.getName().c_str() ) != 0;
}

void LogSettings::setEnabledCategories( const char* szCatList ){
    common::CMutexLock oLock(m_CatLock);

    if ( szCatList && *szCatList )
    	m_strEnabledCategories = szCatList;
    else
    	m_strEnabledCategories = "";
}

void LogSettings::setDisabledCategories( const char* szCatList ){
    common::CMutexLock oLock(m_CatLock);

    if ( szCatList && *szCatList )
    	m_strDisabledCategories = szCatList;
    else
    	m_strDisabledCategories = "";
}

void LogSettings::setExcludeFilter( const String& strExcludeFilter )
{
    if ( strExcludeFilter.length() > 0 )
    {
        rho::common::CTokenizer oTokenizer( strExcludeFilter, "," );
	    while (oTokenizer.hasMoreTokens())
        {
            String tok = rho::String_trim(oTokenizer.nextToken());
		    if (tok.length() == 0)
			    continue;

            //m_arExcludeAttribs.addElement( "\"" + tok + "\"=>\"" );
            m_arExcludeAttribs.addElement( tok );
        }
    }
    else
    	m_arExcludeAttribs.removeAllElements();
}

}

extern "C" {
using namespace rho;
using namespace rho::common;

void rho_logconf_Init(const char* szRootPath, const char* szLogPort){

#ifdef RHODES_EMULATOR
    String strRootPath = szRootPath;
    strRootPath += RHO_EMULATOR_DIR"/";
    rho::common::CFilePath oLogPath( strRootPath );
#else
    rho::common::CFilePath oLogPath( szRootPath );
#endif

    //Set defaults
#ifdef RHO_DEBUG
    LOGCONF().setMinSeverity( L_TRACE );
    LOGCONF().setLogToOutput(true);
    LOGCONF().setEnabledCategories("*");
    LOGCONF().setDisabledCategories("");
#else //!RHO_DEBUG
    LOGCONF().setMinSeverity( L_ERROR );
    LOGCONF().setLogToOutput(false);
    LOGCONF().setEnabledCategories("");
#endif//!RHO_DEBUG

    LOGCONF().setLogPrefix(true);

    rho::String logPath = oLogPath.makeFullPath("RhoLog.txt");
    LOGCONF().setLogToFile(true);
    LOGCONF().setLogFilePath( logPath.c_str() );
    LOGCONF().setMaxLogFileSize(1024*50);

    rho_conf_Init(szRootPath);

    LOGCONF().loadFromConf(RHOCONF());
    if (szLogPort != NULL) {
        LOGCONF().setLogPort(szLogPort);
    }
    else {
        LOGCONF().setLogPort("");
    }
}

char* rho_logconf_getText() {
    rho::String strText;
    LOGCONF().getLogText(strText);
	return strdup(strText.c_str());
}

int rho_logconf_getTextPos() {
	return LOGCONF().getLogTextPos();
}

char* rho_logconf_getEnabledCategories() {
	return strdup(LOGCONF().getEnabledCategories().c_str());
}

char* rho_logconf_getDisabledCategories() {
	return strdup(LOGCONF().getDisabledCategories().c_str());
}

int rho_logconf_getSeverity() {
	return LOGCONF().getMinSeverity();
}

void rho_logconf_setEnabledCategories(const char* categories) {
	LOGCONF().setEnabledCategories(categories);
}

void rho_logconf_setDisabledCategories(const char* categories) {
	LOGCONF().setDisabledCategories(categories);
}

void rho_logconf_setSeverity(int nLevel) {
	LOGCONF().setMinSeverity(nLevel);
}

void rho_logconf_saveSettings() {
	 LOGCONF().saveToFile();
}

void rho_logconf_freeString(char* str) {
	free(str);
}

// RhoConf.set_property_by_name
void rho_conf_set_property_by_name(char* name, char* value)
{
	RHOCONF().setString(name, value, true);

    LOGCONF().loadFromConf(RHOCONF());
}

void rho_conf_clean_log()
{
    LOGCONF().clearLog();
}

#ifndef RHO_NO_RUBY
VALUE rho_conf_get_property_by_name(char* name)
{
	char* szValue = rho_conf_getString(name);

    return rho_ruby_create_string(szValue);
}

VALUE rho_conf_get_conflicts()
{
    CHoldRubyValue hashConflicts(rho_ruby_createHash());

    HashtablePtr<String,Vector<String>* >& mapConflicts = RHOCONF().getConflicts();
    for ( HashtablePtr<String,Vector<String>* >::iterator it=mapConflicts.begin() ; it != mapConflicts.end(); it++ )
    {
        Vector<String>& values = *(it->second);
        CHoldRubyValue arValues(rho_ruby_create_array());
        for( int i = 0; i < (int)values.size(); i++)
            rho_ruby_add_to_array(arValues, rho_ruby_create_string(values.elementAt(i).c_str()) );

        addHashToHash(hashConflicts, it->first.c_str(), arValues);
    }

    return hashConflicts;
}

VALUE rho_conf_read_log(int limit)
{
    VALUE res = rho_ruby_create_string("");
    bool bOldSaveToFile = LOGCONF().isLogToFile();
    LOGCONF().setLogToFile(false);

    rho::common::CRhoFile oFile;
    if ( oFile.open( LOGCONF().getLogFilePath().c_str(), rho::common::CRhoFile::OpenReadOnly) )
    {
        int nFileSize = oFile.size();
        int nPos = LOGCONF().getLogTextPos();
        int nMaxSize = nFileSize > nPos ? nFileSize : nPos;
        if ( limit <= 0 || limit > nMaxSize)
            limit = nMaxSize;

        res = rho_ruby_create_string_withlen(limit);
        char* szStr = getStringFromValue(res);

        if ( limit <= nPos )
        {
            oFile.setPosTo(nPos-limit);
            oFile.readData(szStr,0,limit);
        }else
        {
            oFile.setPosTo(nFileSize-(limit-nPos));
            int nRead = oFile.readData(szStr,0,limit);

            oFile.setPosTo(0);
            oFile.readData(szStr,nRead,limit-nRead);
        }

    }

    LOGCONF().setLogToFile(bOldSaveToFile);

    return res;
}
#endif //RHO_NO_RUBY

}
<commit_msg>Memory leak is fixed in RhoLogConf.cpp<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "RhoLogConf.h"
#include "RhoLogCat.h"
#include "RhoLogSink.h"
#include "common/RhoFile.h"
#include "common/RhoFilePath.h"
#include "common/RhoConf.h"
#include "common/Tokenizer.h"

#ifndef RHO_NO_RUBY
#include "ruby/ext/rho/rhoruby.h"
#endif //RHO_NO_RUBY

namespace rho{
common::CMutex LogSettings::m_FlushLock;
common::CMutex LogSettings::m_CatLock;

LogSettings g_LogSettings;

LogSettings::LogSettings(){
    m_nMinSeverity = 0;
    m_bLogToOutput = true;
    m_bLogToFile = false;
    m_bLogToSocket = false;

    m_nMaxLogFileSize = 0;
    m_bLogPrefix = true;

    m_strLogHost = "PPP_PEER";

    m_pFileSink = new CLogFileSink(*this);
    m_pOutputSink = new CLogOutputSink(*this);
    m_pLogViewSink = NULL;
	m_pSocketSink = NULL;
}

LogSettings::~LogSettings(){
    delete m_pFileSink;
    delete m_pOutputSink;
    delete m_pSocketSink;
}

void LogSettings::setLogPort(const char* szLogPort)
{
	setLogToSocket(true);

	m_strLogPort = rho::String(szLogPort);

	delete m_pSocketSink;
    m_pSocketSink = new CLogSocketSink(*this);
}

void LogSettings::getLogTextW(StringW& strTextW)
{
    boolean bOldSaveToFile = isLogToFile();
    setLogToFile(false);

    common::CRhoFile oFile;
    if ( oFile.open( getLogFilePath().c_str(), common::CRhoFile::OpenReadOnly) )
        oFile.readStringW(strTextW);

    setLogToFile(bOldSaveToFile);
}

void LogSettings::getLogText(String& strText)
{
    boolean bOldSaveToFile = isLogToFile();
    setLogToFile(false);

    common::CRhoFile oFile;
    if ( oFile.open( getLogFilePath().c_str(), common::CRhoFile::OpenReadOnly) )
        oFile.readString(strText);

    setLogToFile(bOldSaveToFile);
}

int LogSettings::getLogTextPos()
{
    return m_pFileSink ? m_pFileSink->getCurPos() : -1;
}

void LogSettings::saveToFile(){
    RHOCONF().setInt("MinSeverity", getMinSeverity(), true );
    RHOCONF().setBool("LogToOutput", isLogToOutput(), true );
    RHOCONF().setBool("LogToFile", isLogToFile(), true );
#if !defined(OS_MACOSX)
    RHOCONF().setString("LogFilePath", getLogFilePath(), true );
#endif
    RHOCONF().setInt("MaxLogFileSize", getMaxLogFileSize(), true );
    RHOCONF().setString("LogCategories", getEnabledCategories(), true );
    RHOCONF().setString("ExcludeLogCategories", getDisabledCategories(), true );
}

void LogSettings::loadFromConf(rho::common::RhoSettings& oRhoConf)
{
    if ( oRhoConf.isExist( "MinSeverity" ) )
        setMinSeverity( oRhoConf.getInt("MinSeverity") );
    if ( oRhoConf.isExist( "LogToOutput") )
        setLogToOutput( oRhoConf.getBool("LogToOutput") );
    if ( oRhoConf.isExist( "LogToFile") )
        setLogToFile( oRhoConf.getBool("LogToFile"));
    if ( oRhoConf.isExist( "LogFilePath") )
        setLogFilePath( oRhoConf.getString("LogFilePath").c_str() );
    if ( oRhoConf.isExist( "MaxLogFileSize") )
        setMaxLogFileSize( oRhoConf.getInt("MaxLogFileSize") );
    if ( oRhoConf.isExist( "LogCategories") )
        setEnabledCategories( oRhoConf.getString("LogCategories").c_str() );
    if (oRhoConf.isExist( "ExcludeLogCategories") )
        setDisabledCategories( oRhoConf.getString("ExcludeLogCategories").c_str() );
	if ( oRhoConf.isExist( "LogToSocket") )
		setLogToSocket( oRhoConf.getBool("LogToSocket") );
	if ( oRhoConf.isExist( "log_exclude_filter") )
        setExcludeFilter( oRhoConf.getString("log_exclude_filter") );
}

void LogSettings::setLogFilePath(const char* szLogFilePath){
    if ( m_strLogFilePath.compare(szLogFilePath) != 0 ){
        common::CMutexLock oLock(m_FlushLock);

        m_strLogFilePath = szLogFilePath;

        if ( m_pFileSink ){
            delete m_pFileSink;
            m_pFileSink = new CLogFileSink(*this);
        }
    }
}

void LogSettings::clearLog(){
    common::CMutexLock oLock(m_FlushLock);

    if ( m_pFileSink ){
        m_pFileSink->clear();
    }

}

void LogSettings::sinkLogMessage( String& strMsg ){
    common::CMutexLock oLock(m_FlushLock);

    if ( isLogToFile() )
        m_pFileSink->writeLogMessage(strMsg);

    if (m_pLogViewSink)
        m_pLogViewSink->writeLogMessage(strMsg);

    //Should be at the end
    if ( isLogToOutput() )
        m_pOutputSink->writeLogMessage(strMsg);

    if ( isLogToSocket() )
        m_pSocketSink->writeLogMessage(strMsg);
}

bool LogSettings::isCategoryEnabled(const LogCategory& cat)const{
    //TODO: Optimize categories search : add map
    common::CMutexLock oLock(m_CatLock);

    if ( m_strDisabledCategories.length() > 0 && strstr(m_strDisabledCategories.c_str(), cat.getName().c_str() ) != 0 )
        return false;

    if ( m_strEnabledCategories.length() == 0 )
        return false;

    return strcmp(m_strEnabledCategories.c_str(),"*") == 0 || strstr(m_strEnabledCategories.c_str(), cat.getName().c_str() ) != 0;
}

void LogSettings::setEnabledCategories( const char* szCatList ){
    common::CMutexLock oLock(m_CatLock);

    if ( szCatList && *szCatList )
    	m_strEnabledCategories = szCatList;
    else
    	m_strEnabledCategories = "";
}

void LogSettings::setDisabledCategories( const char* szCatList ){
    common::CMutexLock oLock(m_CatLock);

    if ( szCatList && *szCatList )
    	m_strDisabledCategories = szCatList;
    else
    	m_strDisabledCategories = "";
}

void LogSettings::setExcludeFilter( const String& strExcludeFilter )
{
    if ( strExcludeFilter.length() > 0 )
    {
        rho::common::CTokenizer oTokenizer( strExcludeFilter, "," );
	    while (oTokenizer.hasMoreTokens())
        {
            String tok = rho::String_trim(oTokenizer.nextToken());
		    if (tok.length() == 0)
			    continue;

            //m_arExcludeAttribs.addElement( "\"" + tok + "\"=>\"" );
            m_arExcludeAttribs.addElement( tok );
        }
    }
    else
    	m_arExcludeAttribs.removeAllElements();
}

}

extern "C" {
using namespace rho;
using namespace rho::common;

void rho_logconf_Init(const char* szRootPath, const char* szLogPort){

#ifdef RHODES_EMULATOR
    String strRootPath = szRootPath;
    strRootPath += RHO_EMULATOR_DIR"/";
    rho::common::CFilePath oLogPath( strRootPath );
#else
    rho::common::CFilePath oLogPath( szRootPath );
#endif

    //Set defaults
#ifdef RHO_DEBUG
    LOGCONF().setMinSeverity( L_TRACE );
    LOGCONF().setLogToOutput(true);
    LOGCONF().setEnabledCategories("*");
    LOGCONF().setDisabledCategories("");
#else //!RHO_DEBUG
    LOGCONF().setMinSeverity( L_ERROR );
    LOGCONF().setLogToOutput(false);
    LOGCONF().setEnabledCategories("");
#endif//!RHO_DEBUG

    LOGCONF().setLogPrefix(true);

    rho::String logPath = oLogPath.makeFullPath("RhoLog.txt");
    LOGCONF().setLogToFile(true);
    LOGCONF().setLogFilePath( logPath.c_str() );
    LOGCONF().setMaxLogFileSize(1024*50);

    rho_conf_Init(szRootPath);

    LOGCONF().loadFromConf(RHOCONF());
    if (szLogPort != NULL) {
        LOGCONF().setLogPort(szLogPort);
    }
    else {
        LOGCONF().setLogPort("");
    }
}

char* rho_logconf_getText() {
    rho::String strText;
    LOGCONF().getLogText(strText);
	return strdup(strText.c_str());
}

int rho_logconf_getTextPos() {
	return LOGCONF().getLogTextPos();
}

char* rho_logconf_getEnabledCategories() {
	return strdup(LOGCONF().getEnabledCategories().c_str());
}

char* rho_logconf_getDisabledCategories() {
	return strdup(LOGCONF().getDisabledCategories().c_str());
}

int rho_logconf_getSeverity() {
	return LOGCONF().getMinSeverity();
}

void rho_logconf_setEnabledCategories(const char* categories) {
	LOGCONF().setEnabledCategories(categories);
}

void rho_logconf_setDisabledCategories(const char* categories) {
	LOGCONF().setDisabledCategories(categories);
}

void rho_logconf_setSeverity(int nLevel) {
	LOGCONF().setMinSeverity(nLevel);
}

void rho_logconf_saveSettings() {
	 LOGCONF().saveToFile();
}

void rho_logconf_freeString(char* str) {
	free(str);
}

// RhoConf.set_property_by_name
void rho_conf_set_property_by_name(char* name, char* value)
{
	RHOCONF().setString(name, value, true);

    LOGCONF().loadFromConf(RHOCONF());
}

void rho_conf_clean_log()
{
    LOGCONF().clearLog();
}

#ifndef RHO_NO_RUBY
VALUE rho_conf_get_property_by_name(char* name)
{
    return rho_ruby_create_string(RHOCONF().getString(name).c_str());
}

VALUE rho_conf_get_conflicts()
{
    CHoldRubyValue hashConflicts(rho_ruby_createHash());

    HashtablePtr<String,Vector<String>* >& mapConflicts = RHOCONF().getConflicts();
    for ( HashtablePtr<String,Vector<String>* >::iterator it=mapConflicts.begin() ; it != mapConflicts.end(); it++ )
    {
        Vector<String>& values = *(it->second);
        CHoldRubyValue arValues(rho_ruby_create_array());
        for( int i = 0; i < (int)values.size(); i++)
            rho_ruby_add_to_array(arValues, rho_ruby_create_string(values.elementAt(i).c_str()) );

        addHashToHash(hashConflicts, it->first.c_str(), arValues);
    }

    return hashConflicts;
}

VALUE rho_conf_read_log(int limit)
{
    VALUE res = rho_ruby_create_string("");
    bool bOldSaveToFile = LOGCONF().isLogToFile();
    LOGCONF().setLogToFile(false);

    rho::common::CRhoFile oFile;
    if ( oFile.open( LOGCONF().getLogFilePath().c_str(), rho::common::CRhoFile::OpenReadOnly) )
    {
        int nFileSize = oFile.size();
        int nPos = LOGCONF().getLogTextPos();
        int nMaxSize = nFileSize > nPos ? nFileSize : nPos;
        if ( limit <= 0 || limit > nMaxSize)
            limit = nMaxSize;

        res = rho_ruby_create_string_withlen(limit);
        char* szStr = getStringFromValue(res);

        if ( limit <= nPos )
        {
            oFile.setPosTo(nPos-limit);
            oFile.readData(szStr,0,limit);
        }else
        {
            oFile.setPosTo(nFileSize-(limit-nPos));
            int nRead = oFile.readData(szStr,0,limit);

            oFile.setPosTo(0);
            oFile.readData(szStr,nRead,limit-nRead);
        }

    }

    LOGCONF().setLogToFile(bOldSaveToFile);

    return res;
}
#endif //RHO_NO_RUBY

}
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Shantanu Tushar <jhahoneyk@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "commentsview.h"
#include "commentsviewitem.h"
#include "newcommentform.h"

#include <lib/models/commentsmodel.h>

#include <KDE/Plasma/ItemBackground>
#include <KDE/Plasma/LineEdit>
#include <KDE/Plasma/Frame>
#include <KDE/Plasma/ScrollWidget>

#include <QtGui/QTreeView>
#include <QtGui/QGraphicsLinearLayout>
#include <QtGui/QGraphicsProxyWidget>

CommentsView::CommentsView( QGraphicsItem* parent, Qt::WindowFlags wFlags )
    : AbstractItemView( parent, wFlags )
    , m_itemBackground( new Plasma::ItemBackground( this ) )
    , m_rootWidget( 0 )
    , m_commentsFrame( new Plasma::Frame( this ) )
    , m_commentsLayout( new QGraphicsLinearLayout( Qt::Vertical, m_commentsFrame ) )
    , m_isOnline( false )
{
    m_commentsFrame->setLayout( m_commentsLayout );
    m_contentLayout->addItem( m_commentsFrame );
}

void CommentsView::setModel( QAbstractItemModel* model )
{
    AbstractItemView::setModel( model );
    connect( model, SIGNAL( modelReset() ), SLOT( reloadComments() ) );

    m_rootWidget = new QGraphicsWidget( m_commentsFrame );
    for( int i = 0; i < m_model->rowCount(); ++i )
    {
        // addComment( m_model->index( i, 0 ), m_rootWidget, 0 );
    }
}

CommentsViewItem* CommentsView::addComment( const QModelIndex& index, QGraphicsWidget* parent, int depth )
{
    CommentsViewItem* item = new CommentsViewItem( parent );
    item->setReplyEnabled( qobject_cast<GluonPlayer::CommentsModel*>( m_model )->isOnline() );
    item->setParent( parent );
    item->setDepth( depth );
    item->setModelIndex( index );
    item->setAcceptHoverEvents( true );
    item->installEventFilter( this );
    connect( item, SIGNAL( replyClicked() ), SLOT( showReply() ) );
    item->setRowInLayout( m_commentsLayout->count() );
    m_commentsLayout->addItem( item );

    if( m_model->hasChildren( index ) )  //There are one or more children
    {
        for( int i = 0; i < m_model->rowCount( index ); ++i )
        {
            addComment( index.child( i, 0 ), item, depth + 1 );
        }
    }

    return item;
}

bool CommentsView::eventFilter( QObject* obj, QEvent* event )
{
    if( event->type() == QEvent::GraphicsSceneHoverEnter )
    {
        QGraphicsItem* item = qobject_cast<QGraphicsItem*> ( obj );
        m_itemBackground->setTargetItem( item );
    }

    return QObject::eventFilter( obj, event );
}

void CommentsView::showReply()
{
    CommentsViewItem* parentItem = qobject_cast<CommentsViewItem*>( sender() );

    hideComments();
    NewCommentForm* form = new NewCommentForm( this );
    m_contentLayout->addItem( form );
    form->setParentIndex( parentItem->modelIndex() );

    connect( form, SIGNAL( accepted( QModelIndex, QString, QString ) ),
             SLOT( addNewUserComment( QModelIndex, QString, QString ) ) );
    connect( form, SIGNAL( canceled() ), SLOT( cancelNewComment() ) );
}

void CommentsView::removeComments()
{
    CommentsViewItem* toDelete;
    //TODO: Make the comments view paged
    while( m_commentsLayout->count() > 0 )   //Remove existing comments from GUI
    {
        toDelete = dynamic_cast<CommentsViewItem*>( m_commentsLayout->itemAt( 0 ) );
        m_commentsLayout->removeAt( 0 );
        toDelete->deleteLater();
    }
}

void CommentsView::loadComments()
{
    for( int i = 0; i < m_model->rowCount(); ++i )  //Reload comments
    {
        addComment( m_model->index( i, 0 ), m_rootWidget, 0 );
    }
}

void CommentsView::reloadComments()
{
    hideComments();
    removeComments();
    loadComments();
    showComments();
}

void CommentsView::addNewUserComment( QModelIndex parentIndex, QString title, QString body )
{
    GluonPlayer::CommentsModel* model = static_cast<GluonPlayer::CommentsModel*>( m_model );
    model->uploadComment( parentIndex, title, body );
    connect( model, SIGNAL( addCommentFailed() ), SLOT( showComments() ) );
    sender()->deleteLater();
}

void CommentsView::cancelNewComment()
{
    sender()->deleteLater();
    showComments();
}

void CommentsView::hideComments()
{
    m_commentsFrame->hide();
    m_contentLayout->removeItem( m_commentsFrame );
}

void CommentsView::showComments()
{
    m_contentLayout->addItem( m_commentsFrame );
    m_commentsFrame->show();
}
<commit_msg>Fix the reply form size. Fix Plasm::ItemBackgroud annoyances.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2010 Shantanu Tushar <jhahoneyk@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "commentsview.h"
#include "commentsviewitem.h"
#include "newcommentform.h"

#include <lib/models/commentsmodel.h>

#include <KDE/Plasma/ItemBackground>
#include <KDE/Plasma/LineEdit>
#include <KDE/Plasma/Frame>

#include <QtGui/QTreeView>
#include <QtGui/QGraphicsLinearLayout>
#include <QtGui/QGraphicsProxyWidget>

CommentsView::CommentsView( QGraphicsItem* parent, Qt::WindowFlags wFlags )
    : AbstractItemView( parent, wFlags )
    , m_itemBackground( new Plasma::ItemBackground( this ) )
    , m_rootWidget( 0 )
    , m_commentsFrame( new Plasma::Frame( this ) )
    , m_commentsLayout( new QGraphicsLinearLayout( Qt::Vertical, m_commentsFrame ) )
    , m_isOnline( false )
{
    m_commentsFrame->setLayout( m_commentsLayout );
    m_contentLayout->addItem( m_commentsFrame );
}

void CommentsView::setModel( QAbstractItemModel* model )
{
    AbstractItemView::setModel( model );
    connect( model, SIGNAL( modelReset() ), SLOT( reloadComments() ) );

    m_rootWidget = new QGraphicsWidget( m_commentsFrame );
    for( int i = 0; i < m_model->rowCount(); ++i )
    {
        // addComment( m_model->index( i, 0 ), m_rootWidget, 0 );
    }
}

CommentsViewItem* CommentsView::addComment( const QModelIndex& index, QGraphicsWidget* parent, int depth )
{
    CommentsViewItem* item = new CommentsViewItem( parent );
    item->setReplyEnabled( qobject_cast<GluonPlayer::CommentsModel*>( m_model )->isOnline() );
    item->setParent( parent );
    item->setDepth( depth );
    item->setModelIndex( index );
    item->setAcceptHoverEvents( true );
    item->installEventFilter( this );
    connect( item, SIGNAL( replyClicked() ), SLOT( showReply() ) );
    item->setRowInLayout( m_commentsLayout->count() );
    m_commentsLayout->addItem( item );

    if( m_model->hasChildren( index ) )  //There are one or more children
    {
        for( int i = 0; i < m_model->rowCount( index ); ++i )
        {
            addComment( index.child( i, 0 ), item, depth + 1 );
        }
    }

    return item;
}

bool CommentsView::eventFilter( QObject* obj, QEvent* event )
{
    if( event->type() == QEvent::GraphicsSceneHoverEnter )
    {
        QGraphicsItem* item = qobject_cast<QGraphicsItem*> ( obj );
        m_itemBackground->setTargetItem( item );
    }

    return QObject::eventFilter( obj, event );
}

void CommentsView::showReply()
{
    CommentsViewItem* parentItem = qobject_cast<CommentsViewItem*>( sender() );

    hideComments();
    NewCommentForm* form = new NewCommentForm( this );
    m_contentLayout->addItem( form );
    form->setParentIndex( parentItem->modelIndex() );
    form->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

    connect( form, SIGNAL( accepted( QModelIndex, QString, QString ) ),
             SLOT( addNewUserComment( QModelIndex, QString, QString ) ) );
    connect( form, SIGNAL( canceled() ), SLOT( cancelNewComment() ) );
}

void CommentsView::removeComments()
{
    CommentsViewItem* toDelete;
    //TODO: Make the comments view paged
    while( m_commentsLayout->count() > 0 )   //Remove existing comments from GUI
    {
        toDelete = dynamic_cast<CommentsViewItem*>( m_commentsLayout->itemAt( 0 ) );
        m_commentsLayout->removeAt( 0 );
        toDelete->deleteLater();
    }
}

void CommentsView::loadComments()
{
    for( int i = 0; i < m_model->rowCount(); ++i )  //Reload comments
    {
        addComment( m_model->index( i, 0 ), m_rootWidget, 0 );
    }
}

void CommentsView::reloadComments()
{
    hideComments();
    removeComments();
    loadComments();
    showComments();
}

void CommentsView::addNewUserComment( QModelIndex parentIndex, QString title, QString body )
{
    GluonPlayer::CommentsModel* model = static_cast<GluonPlayer::CommentsModel*>( m_model );
    model->uploadComment( parentIndex, title, body );
    connect( model, SIGNAL( addCommentFailed() ), SLOT( showComments() ) );
    sender()->deleteLater();
}

void CommentsView::cancelNewComment()
{
    sender()->deleteLater();
    showComments();
}

void CommentsView::hideComments()
{
    m_itemBackground->hide();
    m_commentsFrame->hide();
    m_contentLayout->removeItem( m_commentsFrame );
}

void CommentsView::showComments()
{
    m_itemBackground->show();
    m_contentLayout->addItem( m_commentsFrame );
    m_commentsFrame->show();
}
<|endoftext|>


<commit_before>//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/FileManager.h"
#include "clang/Edit/Commit.h"
#include "clang/Edit/EditedSource.h"
#include "clang/Edit/EditsReceiver.h"
#include "clang/Edit/Rewriters.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/SmallString.h"

using namespace clang;
using namespace arcmt;

namespace {

class ObjCMigrateASTConsumer : public ASTConsumer {
  void migrateDecl(Decl *D);
  void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCInterfaceDecl *D);

public:
  std::string MigrateDir;
  bool MigrateLiterals;
  bool MigrateSubscripting;
  OwningPtr<NSAPI> NSAPIObj;
  OwningPtr<edit::EditedSource> Editor;
  FileRemapper &Remapper;
  FileManager &FileMgr;
  const PPConditionalDirectiveRecord *PPRec;
  Preprocessor &PP;
  bool IsOutputFile;

  ObjCMigrateASTConsumer(StringRef migrateDir,
                         bool migrateLiterals,
                         bool migrateSubscripting,
                         FileRemapper &remapper,
                         FileManager &fileMgr,
                         const PPConditionalDirectiveRecord *PPRec,
                         Preprocessor &PP,
                         bool isOutputFile = false)
  : MigrateDir(migrateDir),
    MigrateLiterals(migrateLiterals),
    MigrateSubscripting(migrateSubscripting),
    Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
    IsOutputFile(isOutputFile) { }

protected:
  virtual void Initialize(ASTContext &Context) {
    NSAPIObj.reset(new NSAPI(Context));
    Editor.reset(new edit::EditedSource(Context.getSourceManager(),
                                        Context.getLangOpts(),
                                        PPRec));
  }

  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
      migrateDecl(*I);
    return true;
  }
  virtual void HandleInterestingDecl(DeclGroupRef DG) {
    // Ignore decls from the PCH.
  }
  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
    ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
  }

  virtual void HandleTranslationUnit(ASTContext &Ctx);
};

}

ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction,
                             StringRef migrateDir,
                             bool migrateLiterals,
                             bool migrateSubscripting)
  : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
    MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting),
    CompInst(0) {
  if (MigrateDir.empty())
    MigrateDir = "."; // user current directory if none is given.
}

ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) {
  PPConditionalDirectiveRecord *
    PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager());
  CompInst->getPreprocessor().addPPCallbacks(PPRec);
  ASTConsumer *
    WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
  ASTConsumer *MTConsumer = new ObjCMigrateASTConsumer(MigrateDir,
                                                       MigrateLiterals,
                                                       MigrateSubscripting,
                                                       Remapper,
                                                    CompInst->getFileManager(),
                                                       PPRec,
                                                       CompInst->getPreprocessor());
  ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer };
  return new MultiplexConsumer(Consumers);
}

bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
  Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
                        /*ignoreIfFilesChanges=*/true);
  CompInst = &CI;
  CI.getDiagnostics().setIgnoreAllWarnings(true);
  return true;
}

namespace {
class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
  ObjCMigrateASTConsumer &Consumer;
  ParentMap &PMap;

public:
  ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
    : Consumer(consumer), PMap(PMap) { }

  bool shouldVisitTemplateInstantiations() const { return false; }
  bool shouldWalkTypesOfTypeLocs() const { return false; }

  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
    if (Consumer.MigrateLiterals) {
      edit::Commit commit(*Consumer.Editor);
      edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
      Consumer.Editor->commit(commit);
    }

    if (Consumer.MigrateSubscripting) {
      edit::Commit commit(*Consumer.Editor);
      edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
      Consumer.Editor->commit(commit);
    }

    return true;
  }

  bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
    // Do depth first; we want to rewrite the subexpressions first so that if
    // we have to move expressions we will move them already rewritten.
    for (Stmt::child_range range = E->children(); range; ++range)
      if (!TraverseStmt(*range))
        return false;

    return WalkUpFromObjCMessageExpr(E);
  }
};

class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
  ObjCMigrateASTConsumer &Consumer;
  OwningPtr<ParentMap> PMap;

public:
  BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }

  bool shouldVisitTemplateInstantiations() const { return false; }
  bool shouldWalkTypesOfTypeLocs() const { return false; }

  bool TraverseStmt(Stmt *S) {
    PMap.reset(new ParentMap(S));
    ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
    return true;
  }
};
}

void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
  if (!D)
    return;
  if (isa<ObjCMethodDecl>(D))
    return; // Wait for the ObjC container declaration.

  BodyMigrator(*this).TraverseDecl(D);
}

void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
                                                      ObjCInterfaceDecl *D) {
  for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
       M != MEnd; ++M) {
    ObjCMethodDecl *Method = (*M);
    if (Method->isPropertyAccessor() ||  Method->param_size() != 0)
      continue;
    // Is this method candidate to be a getter?
    QualType GRT = Method->getResultType();
    if (GRT->isVoidType())
      continue;
    Selector GetterSelector = Method->getSelector();
    IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
    Selector SetterSelector =
      SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
                                             PP.getSelectorTable(),
                                             getterName);
    if (ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true)) {
      // Is this a valid setter, matching the target getter?
      QualType SRT = SetterMethod->getResultType();
      if (!SRT->isVoidType())
        continue;
      const ParmVarDecl *argDecl = *SetterMethod->param_begin();
      // FIXME. Can relax rule for matching getter/setter type further.
      if (!Ctx.hasSameType(argDecl->getType(), GRT))
        continue;
      // we have a matching setter/getter pair.
      // TODO. synthesize a suitable property declaration here.
      }
  }
}

namespace {

class RewritesReceiver : public edit::EditsReceiver {
  Rewriter &Rewrite;

public:
  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }

  virtual void insert(SourceLocation loc, StringRef text) {
    Rewrite.InsertText(loc, text);
  }
  virtual void replace(CharSourceRange range, StringRef text) {
    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
  }
};

}

void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {

  TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
  for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
       D != DEnd; ++D) {
    if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
      migrateObjCInterfaceDecl(Ctx, CDecl);
  }

  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
  RewritesReceiver Rec(rewriter);
  Editor->applyRewrites(Rec);

  for (Rewriter::buffer_iterator
        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
    FileID FID = I->first;
    RewriteBuffer &buf = I->second;
    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
    assert(file);
    SmallString<512> newText;
    llvm::raw_svector_ostream vecOS(newText);
    buf.write(vecOS);
    vecOS.flush();
    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
                   StringRef(newText.data(), newText.size()), file->getName());
    SmallString<64> filePath(file->getName());
    FileMgr.FixupRelativePath(filePath);
    Remapper.remap(filePath.str(), memBuf);
  }

  if (IsOutputFile) {
    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
  } else {
    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
  }
}

bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
  CI.getDiagnostics().setIgnoreAllWarnings(true);
  return true;
}

ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) {
  PPConditionalDirectiveRecord *
    PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager());
  CI.getPreprocessor().addPPCallbacks(PPRec);
  return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile,
                                    /*MigrateLiterals=*/true,
                                    /*MigrateSubscripting=*/true,
                                    Remapper,
                                    CI.getFileManager(),
                                    PPRec,
                                    CI.getPreprocessor(),
                                    /*isOutputFile=*/true);
}
<commit_msg>[ObjectiveC migrator] relax the rules for setter/getter types when deciding on validity of a property inclusion. // rdar://14345082<commit_after>//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/FileManager.h"
#include "clang/Edit/Commit.h"
#include "clang/Edit/EditedSource.h"
#include "clang/Edit/EditsReceiver.h"
#include "clang/Edit/Rewriters.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/SmallString.h"

using namespace clang;
using namespace arcmt;

namespace {

class ObjCMigrateASTConsumer : public ASTConsumer {
  void migrateDecl(Decl *D);
  void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCInterfaceDecl *D);

public:
  std::string MigrateDir;
  bool MigrateLiterals;
  bool MigrateSubscripting;
  OwningPtr<NSAPI> NSAPIObj;
  OwningPtr<edit::EditedSource> Editor;
  FileRemapper &Remapper;
  FileManager &FileMgr;
  const PPConditionalDirectiveRecord *PPRec;
  Preprocessor &PP;
  bool IsOutputFile;

  ObjCMigrateASTConsumer(StringRef migrateDir,
                         bool migrateLiterals,
                         bool migrateSubscripting,
                         FileRemapper &remapper,
                         FileManager &fileMgr,
                         const PPConditionalDirectiveRecord *PPRec,
                         Preprocessor &PP,
                         bool isOutputFile = false)
  : MigrateDir(migrateDir),
    MigrateLiterals(migrateLiterals),
    MigrateSubscripting(migrateSubscripting),
    Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
    IsOutputFile(isOutputFile) { }

protected:
  virtual void Initialize(ASTContext &Context) {
    NSAPIObj.reset(new NSAPI(Context));
    Editor.reset(new edit::EditedSource(Context.getSourceManager(),
                                        Context.getLangOpts(),
                                        PPRec));
  }

  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
      migrateDecl(*I);
    return true;
  }
  virtual void HandleInterestingDecl(DeclGroupRef DG) {
    // Ignore decls from the PCH.
  }
  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
    ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
  }

  virtual void HandleTranslationUnit(ASTContext &Ctx);
};

}

ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction,
                             StringRef migrateDir,
                             bool migrateLiterals,
                             bool migrateSubscripting)
  : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
    MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting),
    CompInst(0) {
  if (MigrateDir.empty())
    MigrateDir = "."; // user current directory if none is given.
}

ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) {
  PPConditionalDirectiveRecord *
    PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager());
  CompInst->getPreprocessor().addPPCallbacks(PPRec);
  ASTConsumer *
    WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
  ASTConsumer *MTConsumer = new ObjCMigrateASTConsumer(MigrateDir,
                                                       MigrateLiterals,
                                                       MigrateSubscripting,
                                                       Remapper,
                                                    CompInst->getFileManager(),
                                                       PPRec,
                                                       CompInst->getPreprocessor());
  ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer };
  return new MultiplexConsumer(Consumers);
}

bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
  Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
                        /*ignoreIfFilesChanges=*/true);
  CompInst = &CI;
  CI.getDiagnostics().setIgnoreAllWarnings(true);
  return true;
}

namespace {
class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
  ObjCMigrateASTConsumer &Consumer;
  ParentMap &PMap;

public:
  ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap)
    : Consumer(consumer), PMap(PMap) { }

  bool shouldVisitTemplateInstantiations() const { return false; }
  bool shouldWalkTypesOfTypeLocs() const { return false; }

  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
    if (Consumer.MigrateLiterals) {
      edit::Commit commit(*Consumer.Editor);
      edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap);
      Consumer.Editor->commit(commit);
    }

    if (Consumer.MigrateSubscripting) {
      edit::Commit commit(*Consumer.Editor);
      edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
      Consumer.Editor->commit(commit);
    }

    return true;
  }

  bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
    // Do depth first; we want to rewrite the subexpressions first so that if
    // we have to move expressions we will move them already rewritten.
    for (Stmt::child_range range = E->children(); range; ++range)
      if (!TraverseStmt(*range))
        return false;

    return WalkUpFromObjCMessageExpr(E);
  }
};

class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
  ObjCMigrateASTConsumer &Consumer;
  OwningPtr<ParentMap> PMap;

public:
  BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }

  bool shouldVisitTemplateInstantiations() const { return false; }
  bool shouldWalkTypesOfTypeLocs() const { return false; }

  bool TraverseStmt(Stmt *S) {
    PMap.reset(new ParentMap(S));
    ObjCMigrator(Consumer, *PMap).TraverseStmt(S);
    return true;
  }
};
}

void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
  if (!D)
    return;
  if (isa<ObjCMethodDecl>(D))
    return; // Wait for the ObjC container declaration.

  BodyMigrator(*this).TraverseDecl(D);
}

void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
                                                      ObjCInterfaceDecl *D) {
  for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
       M != MEnd; ++M) {
    ObjCMethodDecl *Method = (*M);
    if (Method->isPropertyAccessor() ||  Method->param_size() != 0)
      continue;
    // Is this method candidate to be a getter?
    QualType GRT = Method->getResultType();
    if (GRT->isVoidType())
      continue;
    Selector GetterSelector = Method->getSelector();
    IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0);
    Selector SetterSelector =
      SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
                                             PP.getSelectorTable(),
                                             getterName);
    if (ObjCMethodDecl *SetterMethod = D->lookupMethod(SetterSelector, true)) {
      // Is this a valid setter, matching the target getter?
      QualType SRT = SetterMethod->getResultType();
      if (!SRT->isVoidType())
        continue;
      const ParmVarDecl *argDecl = *SetterMethod->param_begin();
      QualType ArgType = argDecl->getType();
      if (!Ctx.hasSameType(ArgType, GRT)) {
        bool Valid =
          ((GRT->isObjCIdType() && ArgType->isObjCObjectPointerType())
            || (ArgType->isObjCIdType() && GRT->isObjCObjectPointerType()));
        if (!Valid)
          continue;
      }
      // we have a matching setter/getter pair.
      // TODO. synthesize a suitable property declaration here.
      }
  }
}

namespace {

class RewritesReceiver : public edit::EditsReceiver {
  Rewriter &Rewrite;

public:
  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }

  virtual void insert(SourceLocation loc, StringRef text) {
    Rewrite.InsertText(loc, text);
  }
  virtual void replace(CharSourceRange range, StringRef text) {
    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
  }
};

}

void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {

  TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
  for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
       D != DEnd; ++D) {
    if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
      migrateObjCInterfaceDecl(Ctx, CDecl);
  }

  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
  RewritesReceiver Rec(rewriter);
  Editor->applyRewrites(Rec);

  for (Rewriter::buffer_iterator
        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
    FileID FID = I->first;
    RewriteBuffer &buf = I->second;
    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
    assert(file);
    SmallString<512> newText;
    llvm::raw_svector_ostream vecOS(newText);
    buf.write(vecOS);
    vecOS.flush();
    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
                   StringRef(newText.data(), newText.size()), file->getName());
    SmallString<64> filePath(file->getName());
    FileMgr.FixupRelativePath(filePath);
    Remapper.remap(filePath.str(), memBuf);
  }

  if (IsOutputFile) {
    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
  } else {
    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
  }
}

bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
  CI.getDiagnostics().setIgnoreAllWarnings(true);
  return true;
}

ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) {
  PPConditionalDirectiveRecord *
    PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager());
  CI.getPreprocessor().addPPCallbacks(PPRec);
  return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile,
                                    /*MigrateLiterals=*/true,
                                    /*MigrateSubscripting=*/true,
                                    Remapper,
                                    CI.getFileManager(),
                                    PPRec,
                                    CI.getPreprocessor(),
                                    /*isOutputFile=*/true);
}
<|endoftext|>


<commit_before>#include "oem/ibm/libpldm/state_set.h"

#include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"

/** @brief PLDM OEM State Set range as per DSP0249_1.1.0 specification
 */
enum pldm_oem_state_set_id_codes
{
    PLDM_OEM_STATE_SET_START = 32768,
    PLDM_OEM_STATE_SET_END = 65535,

};

/** @brief PLDM OEM IBM Code Update possible state set values
 */
enum pldm_oem_ibm_cu_state_set_values
{
    OEM_IBM_STATE_SET_CU_START = 1,
    OEM_IBM_STATE_SET_CU_END = 2,
    OEM_IBM_STATE_SET_CU_FAIL = 3,
    OEM_IBM_STATE_SET_CU_ABORT = 4,
    OEM_IBM_STATE_SET_CU_ACCEPT = 5,
    OEM_IBM_STATE_SET_CU_REJECT = 6,
};

/** @brief PLDM OEM IBM Verification possible state set values
 */
enum pldm_oem_ibm_verification_state_set_values
{
    OEM_IBM_STATE_SET_VERFICATION_VALID = 0,
    OEM_IBM_STATE_SET_VERFICATION_ENTITLEMENT_FAIL = 1,
    OEM_IBM_STATE_SET_VERFICATION_BANNED_PLATFORM_FAIL = 2,
    OEM_IBM_STATE_SET_VERFICATION_MIN_MIF_FAIL = 4,
};

/** @brief PLDM OEM IBM system power state possible state set values
 */
enum pldm_oem_ibm_sys_power_state_set_values
{
    OEM_IBM_STATE_SET_SYS_PWR_STATE_RECYCLE_HARD = 1,
};

/** @brief PLDM OEM IBM boot state possible state set values
 */
enum pldm_oem_ibm_boot_state_set_values
{
    OEM_IBM_STATE_SET_BOOT_STATE_P_SIDE = 1,
    OEM_IBM_STATE_SET_BOOT_STATE_T_SIDE = 2,
};

/** @brief Map for PLDM OEM IBM Entity Types
 */
extern const std::map<uint8_t, std::string> OemIBMEntityType{
    {pldm::responder::oem_ibm_platform::PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
     "OEM IBM Firmware Update"},
    {PLDM_OEM_ENTITY_TYPE_START, "OEM IBM Entity Type Start"},
    {PLDM_OEM_ENTITY_TYPE_END, "OEM IBM Entity Type End"},
};

/** @brief Map for PLDM OEM IBM State Sets
 */
extern const std::map<uint16_t, std::string> OemIBMstateSet{
    {PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, "OEM IBM Firmware Update State"},
    {PLDM_OEM_IBM_BOOT_STATE, "OEM IBM Boot State"},
    {PLDM_OEM_IBM_VERIFICATION_STATE, "OEM IBM Verification State"},
    {PLDM_OEM_IBM_SYSTEM_POWER_STATE, "OEM IBM System Power State"}};

/** @brief Map for PLDM OEM IBM firmware update possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMFWUpdateStateValues{
    {OEM_IBM_STATE_SET_CU_START, "Start"},
    {OEM_IBM_STATE_SET_CU_END, "End"},
    {OEM_IBM_STATE_SET_CU_FAIL, "Fail"},
    {OEM_IBM_STATE_SET_CU_ABORT, "Abort"},
    {OEM_IBM_STATE_SET_CU_ACCEPT, "Accept"},
    {OEM_IBM_STATE_SET_CU_REJECT, "Reject"}};

/** @brief Map for PLDM OEM IBM verification state possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMVerStateValues{
    {OEM_IBM_STATE_SET_VERFICATION_VALID, "Valid"},
    {OEM_IBM_STATE_SET_VERFICATION_ENTITLEMENT_FAIL, "Entitlement Fail"},
    {OEM_IBM_STATE_SET_VERFICATION_BANNED_PLATFORM_FAIL,
     "Banned Platform Fail"},
    {OEM_IBM_STATE_SET_VERFICATION_MIN_MIF_FAIL, "Minimum MIF Fail"}};

/** @brief Map for PLDM OEM IBM systerm power state possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMSysPowerStatesValues{
    {OEM_IBM_STATE_SET_SYS_PWR_STATE_RECYCLE_HARD, "Power Cycle Hard"}};

/** @brief Map for PLDM OEM IBM boot state possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMBootStateValues{
    {OEM_IBM_STATE_SET_BOOT_STATE_P_SIDE, "P Side"},
    {OEM_IBM_STATE_SET_BOOT_STATE_T_SIDE, "T side"}};

/** @brief Map for populating PLDM OEM IBM state sets with possible state values
 */
extern const std::map<uint16_t, const std::map<uint8_t, std::string>>
    populateOemIBMStateMaps{
        {PLDM_OEM_IBM_VERIFICATION_STATE, SetOemIBMVerStateValues},
        {PLDM_OEM_IBM_SYSTEM_POWER_STATE, SetOemIBMSysPowerStatesValues},
        {PLDM_OEM_IBM_BOOT_STATE, SetOemIBMBootStateValues},
        {PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, SetOemIBMFWUpdateStateValues},
    };
<commit_msg>Fix renamed IBM OEM state set header in pldmtool<commit_after>#include "oem/ibm/libpldm/state_set_oem_ibm.h"

#include "oem/ibm/libpldmresponder/oem_ibm_handler.hpp"

/** @brief PLDM OEM State Set range as per DSP0249_1.1.0 specification
 */
enum pldm_oem_state_set_id_codes
{
    PLDM_OEM_STATE_SET_START = 32768,
    PLDM_OEM_STATE_SET_END = 65535,

};

/** @brief PLDM OEM IBM Code Update possible state set values
 */
enum pldm_oem_ibm_cu_state_set_values
{
    OEM_IBM_STATE_SET_CU_START = 1,
    OEM_IBM_STATE_SET_CU_END = 2,
    OEM_IBM_STATE_SET_CU_FAIL = 3,
    OEM_IBM_STATE_SET_CU_ABORT = 4,
    OEM_IBM_STATE_SET_CU_ACCEPT = 5,
    OEM_IBM_STATE_SET_CU_REJECT = 6,
};

/** @brief PLDM OEM IBM Verification possible state set values
 */
enum pldm_oem_ibm_verification_state_set_values
{
    OEM_IBM_STATE_SET_VERFICATION_VALID = 0,
    OEM_IBM_STATE_SET_VERFICATION_ENTITLEMENT_FAIL = 1,
    OEM_IBM_STATE_SET_VERFICATION_BANNED_PLATFORM_FAIL = 2,
    OEM_IBM_STATE_SET_VERFICATION_MIN_MIF_FAIL = 4,
};

/** @brief PLDM OEM IBM system power state possible state set values
 */
enum pldm_oem_ibm_sys_power_state_set_values
{
    OEM_IBM_STATE_SET_SYS_PWR_STATE_RECYCLE_HARD = 1,
};

/** @brief PLDM OEM IBM boot state possible state set values
 */
enum pldm_oem_ibm_boot_state_set_values
{
    OEM_IBM_STATE_SET_BOOT_STATE_P_SIDE = 1,
    OEM_IBM_STATE_SET_BOOT_STATE_T_SIDE = 2,
};

/** @brief Map for PLDM OEM IBM Entity Types
 */
extern const std::map<uint8_t, std::string> OemIBMEntityType{
    {pldm::responder::oem_ibm_platform::PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE,
     "OEM IBM Firmware Update"},
    {PLDM_OEM_ENTITY_TYPE_START, "OEM IBM Entity Type Start"},
    {PLDM_OEM_ENTITY_TYPE_END, "OEM IBM Entity Type End"},
};

/** @brief Map for PLDM OEM IBM State Sets
 */
extern const std::map<uint16_t, std::string> OemIBMstateSet{
    {PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, "OEM IBM Firmware Update State"},
    {PLDM_OEM_IBM_BOOT_STATE, "OEM IBM Boot State"},
    {PLDM_OEM_IBM_VERIFICATION_STATE, "OEM IBM Verification State"},
    {PLDM_OEM_IBM_SYSTEM_POWER_STATE, "OEM IBM System Power State"}};

/** @brief Map for PLDM OEM IBM firmware update possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMFWUpdateStateValues{
    {OEM_IBM_STATE_SET_CU_START, "Start"},
    {OEM_IBM_STATE_SET_CU_END, "End"},
    {OEM_IBM_STATE_SET_CU_FAIL, "Fail"},
    {OEM_IBM_STATE_SET_CU_ABORT, "Abort"},
    {OEM_IBM_STATE_SET_CU_ACCEPT, "Accept"},
    {OEM_IBM_STATE_SET_CU_REJECT, "Reject"}};

/** @brief Map for PLDM OEM IBM verification state possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMVerStateValues{
    {OEM_IBM_STATE_SET_VERFICATION_VALID, "Valid"},
    {OEM_IBM_STATE_SET_VERFICATION_ENTITLEMENT_FAIL, "Entitlement Fail"},
    {OEM_IBM_STATE_SET_VERFICATION_BANNED_PLATFORM_FAIL,
     "Banned Platform Fail"},
    {OEM_IBM_STATE_SET_VERFICATION_MIN_MIF_FAIL, "Minimum MIF Fail"}};

/** @brief Map for PLDM OEM IBM systerm power state possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMSysPowerStatesValues{
    {OEM_IBM_STATE_SET_SYS_PWR_STATE_RECYCLE_HARD, "Power Cycle Hard"}};

/** @brief Map for PLDM OEM IBM boot state possible state values
 */
extern const std::map<uint8_t, std::string> SetOemIBMBootStateValues{
    {OEM_IBM_STATE_SET_BOOT_STATE_P_SIDE, "P Side"},
    {OEM_IBM_STATE_SET_BOOT_STATE_T_SIDE, "T side"}};

/** @brief Map for populating PLDM OEM IBM state sets with possible state values
 */
extern const std::map<uint16_t, const std::map<uint8_t, std::string>>
    populateOemIBMStateMaps{
        {PLDM_OEM_IBM_VERIFICATION_STATE, SetOemIBMVerStateValues},
        {PLDM_OEM_IBM_SYSTEM_POWER_STATE, SetOemIBMSysPowerStatesValues},
        {PLDM_OEM_IBM_BOOT_STATE, SetOemIBMBootStateValues},
        {PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE, SetOemIBMFWUpdateStateValues},
    };
<|endoftext|>