<commit_before>#include "CppUnitTest.h"
#include <algorithm>
#include <sstream>
#include <cctype>
#include <string>
#include <vector>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace algo
{
    struct token
    {
        enum toktype { root_node, named_node, edge_name, horizontal_edge, ascending_edge_part, descending_edge_part, vertical_edge_part };
        toktype type;
        string name;
    };

    bool operator==(const token& lhs, const token& rhs)
    {
        return lhs.type == rhs.type
            && lhs.name == rhs.name;
    }

    struct ascii_tree
    {
        static vector<token> tokenize(const string& s)
        {
            vector<token> tokens;
            enum { none, open_square_brace, close_square_brace, asterisk, dash, name_char } prev = none;
            size_t marker = 0, marked_length = 0;

            for (size_t i = 0; i < s.size(); ++i)
            {
                auto ch = s[i];

                if (ch == '[')
                {
                    prev = open_square_brace;
                }
                else if (ch == ']')
                {
                    if (prev == asterisk)
                    {
                        tokens.emplace_back(token { token::root_node, "" });
                    }
                    else
                    {
                        tokens.emplace_back(token { token::named_node, s.substr(marker, marked_length) });
                    }

                    prev = close_square_brace;
                }
                else if (ch == '*')
                {
                    prev = asterisk;
                }
                else if (ch == '-')
                {
                    if (prev == name_char)
                    {
                        tokens.emplace_back(token { token::horizontal_edge, s.substr(marker, marked_length) });
                    }

                    prev = dash;
                }
                else if (ch == '/')
                {
                    tokens.emplace_back(token { token::ascending_edge_part, "" });
                }
                else if (ch == '\\')
                {
                    tokens.emplace_back(token { token::descending_edge_part, "" });
                }
                else if (ch == '|')
                {
                    tokens.emplace_back(token { token::vertical_edge_part, "" });
                }
                else if (isalnum(ch) || ch == '_')
                {
                    if (prev != name_char)
                    {
                        marker = i;
                        marked_length = 0;
                    }

                    prev = name_char;
                    ++marked_length;
                }
            }

            if (prev == name_char)
            {
                tokens.emplace_back(token { token::edge_name, s.substr(marker, marked_length) });
            }

            return tokens;
        }
    };
}

namespace Microsoft { namespace VisualStudio { namespace CppUnitTestFramework
{
    template<>
    wstring ToString<algo::token::toktype>(const algo::token::toktype& type)
    {
        switch (type)
        {
        case algo::token::root_node:
            return L"root_node";
        case algo::token::named_node:
            return L"named_node";
        case algo::token::edge_name:
            return L"edge_name";
        case algo::token::horizontal_edge:
            return L"horizontal_edge";
        case algo::token::ascending_edge_part:
            return L"ascending_edge_part";
        case algo::token::descending_edge_part:
            return L"descending_edge_part";
        case algo::token::vertical_edge_part:
            return L"vertical_edge_part";
        default:
            return L"unknown token";
        }
    }
}}}

namespace algo { namespace spec
{
	TEST_CLASS(can_recognize_ascii_tree_tokens)
	{
        void tokens_should_match_(std::initializer_list<token> expected, vector<token>& actual)
        {
            auto mismatch_pair = std::mismatch(expected.begin(), expected.end(), actual.begin());

            if (mismatch_pair.first != expected.end() || mismatch_pair.second != actual.end())
            {
                wstring expectedName(mismatch_pair.first->name.begin(), mismatch_pair.first->name.end());
                wstring actualName(mismatch_pair.second->name.begin(), mismatch_pair.second->name.end());

                wstring message = L"Expected: " + ToString(mismatch_pair.first->type) + L" \"" + expectedName + L"\" "
                    + L"Actual: " + ToString(mismatch_pair.second->type) + L" \"" + actualName + L"\"";

                Assert::Fail(message.c_str());
            }
        }

    public:

        TEST_METHOD(should_not_recognize_any_tokens_in_an_empty_string)
        {
            auto tokens = ascii_tree::tokenize("");
            Assert::IsTrue(tokens.empty());
        }

		TEST_METHOD(should_recognize_a_root_node)
		{
            auto tokens = ascii_tree::tokenize("[*]");
            Assert::AreEqual(token::root_node, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_root_node_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" [ * ]");
            Assert::AreEqual(token::root_node, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_named_node)
        {
            const string all_chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            auto tokens = ascii_tree::tokenize("[" + all_chars + "]");
            Assert::AreEqual(token::named_node, tokens.front().type);
            Assert::AreEqual(all_chars.c_str(), tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_a_named_node_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" [ a ]");
            Assert::AreEqual(token::named_node, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_an_edge_name)
        {
            auto tokens = ascii_tree::tokenize("a");
            Assert::AreEqual(token::edge_name, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_an_edge_name_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" a ");
            Assert::AreEqual(token::edge_name, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("/");
            Assert::AreEqual(token::ascending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" / ");
            Assert::AreEqual(token::ascending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_descending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("\\");
            Assert::AreEqual(token::descending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" \\ ");
            Assert::AreEqual(token::descending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part)
        {
            auto tokens = ascii_tree::tokenize("|");
            Assert::AreEqual(token::vertical_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" | ");
            Assert::AreEqual(token::vertical_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_horizontal_edge)
        {
            auto tokens = ascii_tree::tokenize("-a-");
            Assert::AreEqual(token::horizontal_edge, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" - a - ");
            Assert::AreEqual(token::horizontal_edge, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_named_node)
        {
            auto tokens = ascii_tree::tokenize("[*][a]");
            tokens_should_match_({ { token::root_node, "" }, { token::named_node, "a" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_horizontal_edge)
        {
            auto tokens = ascii_tree::tokenize("[*]-a-");
            tokens_should_match_({ { token::root_node, "" }, { token::horizontal_edge, "a" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_next_to_a_named_node)
        {
            auto tokens = ascii_tree::tokenize("-a-[b]");
            tokens_should_match_({ { token::horizontal_edge, "a" }, { token::named_node, "b" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_descending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("[*]\\");
            tokens_should_match_({ { token::root_node, "" }, { token::descending_edge_part, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_ascending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("[*]/");
            tokens_should_match_({ { token::root_node, "" }, { token::ascending_edge_part, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_vertical_edge_part)
        {
            auto tokens = ascii_tree::tokenize("[*]|");
            tokens_should_match_({ { token::root_node, "" }, { token::vertical_edge_part, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_edge_name)
        {
            auto tokens = ascii_tree::tokenize("[*]a");
            tokens_should_match_({ { token::root_node, "" }, { token::edge_name, "a" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_root_node)
        {
            auto tokens = ascii_tree::tokenize("[a][*]");
            tokens_should_match_({ { token::named_node, "a" }, { token::root_node, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_named_node)
        {
            auto tokens = ascii_tree::tokenize("[a][b]");
            tokens_should_match_({ { token::named_node, "a" }, { token::named_node, "b" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_horizontal_edge)
        {
            auto tokens = ascii_tree::tokenize("[a]-b-");
            tokens_should_match_({ { token::named_node, "a" }, { token::horizontal_edge, "b" } }, tokens);
        }

    };
}}
<commit_msg>untabify<commit_after>#include "CppUnitTest.h"
#include <algorithm>
#include <sstream>
#include <cctype>
#include <string>
#include <vector>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace std;

namespace algo
{
    struct token
    {
        enum toktype { root_node, named_node, edge_name, horizontal_edge, ascending_edge_part, descending_edge_part, vertical_edge_part };
        toktype type;
        string name;
    };

    bool operator==(const token& lhs, const token& rhs)
    {
        return lhs.type == rhs.type
            && lhs.name == rhs.name;
    }

    struct ascii_tree
    {
        static vector<token> tokenize(const string& s)
        {
            vector<token> tokens;
            enum { none, open_square_brace, close_square_brace, asterisk, dash, name_char } prev = none;
            size_t marker = 0, marked_length = 0;

            for (size_t i = 0; i < s.size(); ++i)
            {
                auto ch = s[i];

                if (ch == '[')
                {
                    prev = open_square_brace;
                }
                else if (ch == ']')
                {
                    if (prev == asterisk)
                    {
                        tokens.emplace_back(token { token::root_node, "" });
                    }
                    else
                    {
                        tokens.emplace_back(token { token::named_node, s.substr(marker, marked_length) });
                    }

                    prev = close_square_brace;
                }
                else if (ch == '*')
                {
                    prev = asterisk;
                }
                else if (ch == '-')
                {
                    if (prev == name_char)
                    {
                        tokens.emplace_back(token { token::horizontal_edge, s.substr(marker, marked_length) });
                    }

                    prev = dash;
                }
                else if (ch == '/')
                {
                    tokens.emplace_back(token { token::ascending_edge_part, "" });
                }
                else if (ch == '\\')
                {
                    tokens.emplace_back(token { token::descending_edge_part, "" });
                }
                else if (ch == '|')
                {
                    tokens.emplace_back(token { token::vertical_edge_part, "" });
                }
                else if (isalnum(ch) || ch == '_')
                {
                    if (prev != name_char)
                    {
                        marker = i;
                        marked_length = 0;
                    }

                    prev = name_char;
                    ++marked_length;
                }
            }

            if (prev == name_char)
            {
                tokens.emplace_back(token { token::edge_name, s.substr(marker, marked_length) });
            }

            return tokens;
        }
    };
}

namespace Microsoft { namespace VisualStudio { namespace CppUnitTestFramework
{
    template<>
    wstring ToString<algo::token::toktype>(const algo::token::toktype& type)
    {
        switch (type)
        {
        case algo::token::root_node:
            return L"root_node";
        case algo::token::named_node:
            return L"named_node";
        case algo::token::edge_name:
            return L"edge_name";
        case algo::token::horizontal_edge:
            return L"horizontal_edge";
        case algo::token::ascending_edge_part:
            return L"ascending_edge_part";
        case algo::token::descending_edge_part:
            return L"descending_edge_part";
        case algo::token::vertical_edge_part:
            return L"vertical_edge_part";
        default:
            return L"unknown token";
        }
    }
}}}

namespace algo { namespace spec
{
    TEST_CLASS(can_recognize_ascii_tree_tokens)
    {
        void tokens_should_match_(std::initializer_list<token> expected, vector<token>& actual)
        {
            auto mismatch_pair = std::mismatch(expected.begin(), expected.end(), actual.begin());

            if (mismatch_pair.first != expected.end() || mismatch_pair.second != actual.end())
            {
                wstring expectedName(mismatch_pair.first->name.begin(), mismatch_pair.first->name.end());
                wstring actualName(mismatch_pair.second->name.begin(), mismatch_pair.second->name.end());

                wstring message = L"Expected: " + ToString(mismatch_pair.first->type) + L" \"" + expectedName + L"\" "
                    + L"Actual: " + ToString(mismatch_pair.second->type) + L" \"" + actualName + L"\"";

                Assert::Fail(message.c_str());
            }
        }

    public:

        TEST_METHOD(should_not_recognize_any_tokens_in_an_empty_string)
        {
            auto tokens = ascii_tree::tokenize("");
            Assert::IsTrue(tokens.empty());
        }

        TEST_METHOD(should_recognize_a_root_node)
        {
            auto tokens = ascii_tree::tokenize("[*]");
            Assert::AreEqual(token::root_node, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_root_node_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" [ * ]");
            Assert::AreEqual(token::root_node, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_named_node)
        {
            const string all_chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            auto tokens = ascii_tree::tokenize("[" + all_chars + "]");
            Assert::AreEqual(token::named_node, tokens.front().type);
            Assert::AreEqual(all_chars.c_str(), tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_a_named_node_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" [ a ]");
            Assert::AreEqual(token::named_node, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_an_edge_name)
        {
            auto tokens = ascii_tree::tokenize("a");
            Assert::AreEqual(token::edge_name, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_an_edge_name_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" a ");
            Assert::AreEqual(token::edge_name, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("/");
            Assert::AreEqual(token::ascending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_an_ascending_edge_part_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" / ");
            Assert::AreEqual(token::ascending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_descending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("\\");
            Assert::AreEqual(token::descending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_descending_edge_part_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" \\ ");
            Assert::AreEqual(token::descending_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part)
        {
            auto tokens = ascii_tree::tokenize("|");
            Assert::AreEqual(token::vertical_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_vertical_edge_part_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" | ");
            Assert::AreEqual(token::vertical_edge_part, tokens.front().type);
        }

        TEST_METHOD(should_recognize_a_horizontal_edge)
        {
            auto tokens = ascii_tree::tokenize("-a-");
            Assert::AreEqual(token::horizontal_edge, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_with_spaces)
        {
            auto tokens = ascii_tree::tokenize(" - a - ");
            Assert::AreEqual(token::horizontal_edge, tokens.front().type);
            Assert::AreEqual("a", tokens.front().name.c_str());
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_named_node)
        {
            auto tokens = ascii_tree::tokenize("[*][a]");
            tokens_should_match_({ { token::root_node, "" }, { token::named_node, "a" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_horizontal_edge)
        {
            auto tokens = ascii_tree::tokenize("[*]-a-");
            tokens_should_match_({ { token::root_node, "" }, { token::horizontal_edge, "a" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_horizontal_edge_next_to_a_named_node)
        {
            auto tokens = ascii_tree::tokenize("-a-[b]");
            tokens_should_match_({ { token::horizontal_edge, "a" }, { token::named_node, "b" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_descending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("[*]\\");
            tokens_should_match_({ { token::root_node, "" }, { token::descending_edge_part, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_ascending_edge_part)
        {
            auto tokens = ascii_tree::tokenize("[*]/");
            tokens_should_match_({ { token::root_node, "" }, { token::ascending_edge_part, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_a_vertical_edge_part)
        {
            auto tokens = ascii_tree::tokenize("[*]|");
            tokens_should_match_({ { token::root_node, "" }, { token::vertical_edge_part, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_root_node_next_to_an_edge_name)
        {
            auto tokens = ascii_tree::tokenize("[*]a");
            tokens_should_match_({ { token::root_node, "" }, { token::edge_name, "a" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_root_node)
        {
            auto tokens = ascii_tree::tokenize("[a][*]");
            tokens_should_match_({ { token::named_node, "a" }, { token::root_node, "" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_named_node)
        {
            auto tokens = ascii_tree::tokenize("[a][b]");
            tokens_should_match_({ { token::named_node, "a" }, { token::named_node, "b" } }, tokens);
        }

        TEST_METHOD(should_recognize_a_named_node_next_to_a_horizontal_edge)
        {
            auto tokens = ascii_tree::tokenize("[a]-b-");
            tokens_should_match_({ { token::named_node, "a" }, { token::horizontal_edge, "b" } }, tokens);
        }

    };
}}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: apinotifierimpl.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: jb $ $Date: 2002-02-11 13:47:53 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "apinotifierimpl.hxx"

#ifndef CONFIGMGR_API_NODEACCESS_HXX_
#include "apinodeaccess.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif
#ifndef CONFIGMGR_CONFIGVALUEREF_HXX_
#include "valueref.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNOTIFIER_HXX_
#include "confignotifier.hxx"
#endif
#ifndef CONFIGMGR_CONFIGEXCEPT_HXX_
#include "configexcept.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

namespace configmgr
{
    namespace configapi
    {
//-----------------------------------------------------------------------------------
        namespace lang = css::lang;
        namespace util = css::util;
        namespace beans = css::beans;

        using uno::RuntimeException;
        using uno::Reference;

        using configuration::NodeRef;
        using configuration::ValueRef;
        using configuration::Tree;

// Generic Notifier Support Implementations
//-----------------------------------------------------------------------------------

/// add a Listener to the notifier of a NodeAccess
template <class Listener>
inline
void genericAddListener(NodeAccess& rNode, const Reference< Listener >& xListener )
{
    GuardedNotifier aGuardedNotifier( rNode );  // guard the notifier
    aGuardedNotifier->add(rNode.getNodeRef(), xListener);
}

/// remove a Listener from the notifier of a NodeAccess
template <class Listener>
inline
void genericRemoveListener(NodeAccess& rNode, const Reference< Listener >& xListener )
{
    GuardedNotifier aGuardedNotifier( rNode );  // guard the notifier
    aGuardedNotifier->remove(rNode.getNodeRef(), xListener);
}

/** add a Listener for all or some children of a NodeAccess to its notifier

 If the name given is empty, the listener will be added to all children of the node

    @returns
        <TRUE/>  if the node was found, or the name was empty
        <FALSE/> if the named node wasn't found
*/
template <class Listener>
inline
bool genericAddChildListener(NodeGroupInfoAccess& rNode, const Reference< Listener >& xListener, const OUString& sName )
{
    using configuration::validateChildName;

    if (sName.getLength() != 0)
    {
        GuardedNodeDataAccess       aGuardedNode( rNode );      // guard access to children
        GuardedNotifier             aGuardedNotifier( rNode );  // guard the notifier

        Tree        aTree( aGuardedNode.getTree() );
        NodeRef     aNode( aGuardedNode.getNode() );

        Name        aChildName = validateChildName(sName,aTree,aNode);

        if (!aTree.hasChild(aNode,aChildName)) return false;

        aGuardedNotifier->addForOne(aNode, xListener, aChildName);
    }
    else
    {
        GuardedNotifier  aGuardedNotifier( rNode ); // guard the notifier

        aGuardedNotifier->addForAll(rNode.getNodeRef(), xListener);

        // always ok, as we addreess no specific NodeRef
    }
    return true;
}

/** remove a Listener from all or some children of a NodeAccess to its notifier

 If the name given is empty, the listener will be removed from any children of the node

    @returns
        <TRUE/>  if the node was found, or the name was empty
        <FALSE/> if the named node wasn't found
*/
template <class Listener>
inline
bool genericRemoveChildListener(NodeGroupInfoAccess& rNode, const Reference< Listener >& xListener, const OUString& sName )
{
    using configuration::validateChildName;

    if (sName.getLength() != 0)
    {
        GuardedNodeDataAccess       aGuardedNode( rNode );      // guard access to children
        GuardedNotifier             aGuardedNotifier( rNode );  // guard the notifier

        Tree        aTree( aGuardedNode.getTree() );
        NodeRef     aNode( aGuardedNode.getNode() );

        Name        aChildName = validateChildName(sName,aTree,aNode);

        if (!aTree.hasChild(aNode,aChildName)) return false;

        aGuardedNotifier->removeForOne(aNode, xListener, aChildName);
    }
    else
    {
        GuardedNotifier  aGuardedNotifier( rNode ); // guard the notifier

        aGuardedNotifier->removeForAll(rNode.getNodeRef(), xListener);

        // always ok, as we addreess no specific NodeRef
    }
    return true;
}

// XComponent
//-----------------------------------------------------------------------------------
void implAddListener(NodeAccess& rNode, const Reference< css::lang::XEventListener >& xListener )
    throw(RuntimeException)
{
    genericAddListener(rNode,xListener);
}

void implRemoveListener(NodeAccess& rNode, const Reference< css::lang::XEventListener >& xListener )
    throw(RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XContainer
//-----------------------------------------------------------------------------------
void implAddListener(NodeAccess& rNode, const Reference< css::container::XContainerListener >& xListener )
    throw(RuntimeException)
{
    genericAddListener(rNode,xListener);
}

void implRemoveListener(NodeAccess& rNode, const Reference< css::container::XContainerListener >& xListener )
    throw(RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XChangesNotifier
//-----------------------------------------------------------------------------------

void implAddListener(NodeAccess& rNode, const Reference< css::util::XChangesListener >& xListener )
    throw(RuntimeException)
{
    genericAddListener(rNode,xListener);
}

void implRemoveListener(NodeAccess& rNode, const Reference< css::util::XChangesListener >& xListener )
    throw(RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XMultiPropertySet
//-----------------------------------------------------------------------------------

void implAddListener( NodeAccess& rNode, const uno::Reference< beans::XPropertiesChangeListener >& xListener, const uno::Sequence< OUString >& aPropertyNames )
    throw(uno::RuntimeException)
{

    GuardedNotifier impl( rNode );

    // TODO: is an exception for unknown names allowed/needed ?
    impl->add(rNode.getNodeRef(), xListener, aPropertyNames);
}

void implRemoveListener( NodeAccess& rNode, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
    throw(uno::RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XPropertySet (manages listeners associated with named child node)
//-----------------------------------------------------------------------------------

// XPropertySet - VetoableChangeListeners
//-----------------------------------------------------------------------------------

void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XVetoableChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericAddChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: adding a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }

}

void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XVetoableChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericRemoveChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: removing a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }
}

// XPropertySet - PropertyChangeListeners
//-----------------------------------------------------------------------------------

void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XPropertyChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericAddChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: adding a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }
}

void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XPropertyChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericRemoveChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: removing a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }
}

//-----------------------------------------------------------------------------------
    } // namespace configapi

} // namespace configmgr

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.222); FILE MERGED 2005/09/05 17:03:30 rt 1.5.222.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: apinotifierimpl.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 03:08:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "apinotifierimpl.hxx"

#ifndef CONFIGMGR_API_NODEACCESS_HXX_
#include "apinodeaccess.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif
#ifndef CONFIGMGR_CONFIGVALUEREF_HXX_
#include "valueref.hxx"
#endif
#ifndef CONFIGMGR_CONFIGNOTIFIER_HXX_
#include "confignotifier.hxx"
#endif
#ifndef CONFIGMGR_CONFIGEXCEPT_HXX_
#include "configexcept.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

namespace configmgr
{
    namespace configapi
    {
//-----------------------------------------------------------------------------------
        namespace lang = css::lang;
        namespace util = css::util;
        namespace beans = css::beans;

        using uno::RuntimeException;
        using uno::Reference;

        using configuration::NodeRef;
        using configuration::ValueRef;
        using configuration::Tree;

// Generic Notifier Support Implementations
//-----------------------------------------------------------------------------------

/// add a Listener to the notifier of a NodeAccess
template <class Listener>
inline
void genericAddListener(NodeAccess& rNode, const Reference< Listener >& xListener )
{
    GuardedNotifier aGuardedNotifier( rNode );  // guard the notifier
    aGuardedNotifier->add(rNode.getNodeRef(), xListener);
}

/// remove a Listener from the notifier of a NodeAccess
template <class Listener>
inline
void genericRemoveListener(NodeAccess& rNode, const Reference< Listener >& xListener )
{
    GuardedNotifier aGuardedNotifier( rNode );  // guard the notifier
    aGuardedNotifier->remove(rNode.getNodeRef(), xListener);
}

/** add a Listener for all or some children of a NodeAccess to its notifier

 If the name given is empty, the listener will be added to all children of the node

    @returns
        <TRUE/>  if the node was found, or the name was empty
        <FALSE/> if the named node wasn't found
*/
template <class Listener>
inline
bool genericAddChildListener(NodeGroupInfoAccess& rNode, const Reference< Listener >& xListener, const OUString& sName )
{
    using configuration::validateChildName;

    if (sName.getLength() != 0)
    {
        GuardedNodeDataAccess       aGuardedNode( rNode );      // guard access to children
        GuardedNotifier             aGuardedNotifier( rNode );  // guard the notifier

        Tree        aTree( aGuardedNode.getTree() );
        NodeRef     aNode( aGuardedNode.getNode() );

        Name        aChildName = validateChildName(sName,aTree,aNode);

        if (!aTree.hasChild(aNode,aChildName)) return false;

        aGuardedNotifier->addForOne(aNode, xListener, aChildName);
    }
    else
    {
        GuardedNotifier  aGuardedNotifier( rNode ); // guard the notifier

        aGuardedNotifier->addForAll(rNode.getNodeRef(), xListener);

        // always ok, as we addreess no specific NodeRef
    }
    return true;
}

/** remove a Listener from all or some children of a NodeAccess to its notifier

 If the name given is empty, the listener will be removed from any children of the node

    @returns
        <TRUE/>  if the node was found, or the name was empty
        <FALSE/> if the named node wasn't found
*/
template <class Listener>
inline
bool genericRemoveChildListener(NodeGroupInfoAccess& rNode, const Reference< Listener >& xListener, const OUString& sName )
{
    using configuration::validateChildName;

    if (sName.getLength() != 0)
    {
        GuardedNodeDataAccess       aGuardedNode( rNode );      // guard access to children
        GuardedNotifier             aGuardedNotifier( rNode );  // guard the notifier

        Tree        aTree( aGuardedNode.getTree() );
        NodeRef     aNode( aGuardedNode.getNode() );

        Name        aChildName = validateChildName(sName,aTree,aNode);

        if (!aTree.hasChild(aNode,aChildName)) return false;

        aGuardedNotifier->removeForOne(aNode, xListener, aChildName);
    }
    else
    {
        GuardedNotifier  aGuardedNotifier( rNode ); // guard the notifier

        aGuardedNotifier->removeForAll(rNode.getNodeRef(), xListener);

        // always ok, as we addreess no specific NodeRef
    }
    return true;
}

// XComponent
//-----------------------------------------------------------------------------------
void implAddListener(NodeAccess& rNode, const Reference< css::lang::XEventListener >& xListener )
    throw(RuntimeException)
{
    genericAddListener(rNode,xListener);
}

void implRemoveListener(NodeAccess& rNode, const Reference< css::lang::XEventListener >& xListener )
    throw(RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XContainer
//-----------------------------------------------------------------------------------
void implAddListener(NodeAccess& rNode, const Reference< css::container::XContainerListener >& xListener )
    throw(RuntimeException)
{
    genericAddListener(rNode,xListener);
}

void implRemoveListener(NodeAccess& rNode, const Reference< css::container::XContainerListener >& xListener )
    throw(RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XChangesNotifier
//-----------------------------------------------------------------------------------

void implAddListener(NodeAccess& rNode, const Reference< css::util::XChangesListener >& xListener )
    throw(RuntimeException)
{
    genericAddListener(rNode,xListener);
}

void implRemoveListener(NodeAccess& rNode, const Reference< css::util::XChangesListener >& xListener )
    throw(RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XMultiPropertySet
//-----------------------------------------------------------------------------------

void implAddListener( NodeAccess& rNode, const uno::Reference< beans::XPropertiesChangeListener >& xListener, const uno::Sequence< OUString >& aPropertyNames )
    throw(uno::RuntimeException)
{

    GuardedNotifier impl( rNode );

    // TODO: is an exception for unknown names allowed/needed ?
    impl->add(rNode.getNodeRef(), xListener, aPropertyNames);
}

void implRemoveListener( NodeAccess& rNode, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
    throw(uno::RuntimeException)
{
    genericRemoveListener(rNode,xListener);
}

// XPropertySet (manages listeners associated with named child node)
//-----------------------------------------------------------------------------------

// XPropertySet - VetoableChangeListeners
//-----------------------------------------------------------------------------------

void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XVetoableChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericAddChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: adding a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }

}

void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XVetoableChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericRemoveChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: removing a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }
}

// XPropertySet - PropertyChangeListeners
//-----------------------------------------------------------------------------------

void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XPropertyChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericAddChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: adding a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }
}

void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XPropertyChangeListener >& xListener, const OUString& sPropertyName )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    using namespace css::beans;
    try
    {
        if (!genericRemoveChildListener(rNode,xListener,sPropertyName))
        {
            throw UnknownPropertyException(
                    OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found !")),
                    rNode.getUnoInstance() );
        }
    }
    catch (configuration::InvalidName& ex)
    {
        ExceptionMapper e(ex);
        throw UnknownPropertyException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found:")) += ex.message(),
                rNode.getUnoInstance() );
    }
    catch (configuration::WrappedUnoException& ex)
    {
        throw css::lang::WrappedTargetException(
                OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: removing a listener failed: ")) += ex.message(),
                rNode.getUnoInstance(),
                ex.getAnyUnoException());
    }
    catch (configuration::Exception& ex)
    {
        ExceptionMapper e(ex);
        e.setContext( rNode.getUnoInstance() );
        e.unhandled();
    }
}

//-----------------------------------------------------------------------------------
    } // namespace configapi

} // namespace configmgr

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: providerfactory.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: jb $ $Date: 2001-05-18 16:16:52 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>
#ifndef _CONFIGMGR_PROVIDER_FACTORY_HXX_
#include "providerfactory.hxx"
#endif

#ifndef _UNO_LBNAMES_H_
#include <uno/lbnames.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "confapifactory.hxx"
#endif
#ifndef CONFIGMGR_API_SVCCOMPONENT_HXX_
#include "confsvccomponent.hxx"
#endif
#ifndef CONFIGMGR_BOOTSTRAP_HXX_
#include "bootstrap.hxx"
#endif

// #include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/lang/XComponent.hpp>

#define THISREF() static_cast< ::cppu::OWeakObject* >(this)

//........................................................................
namespace configmgr
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;
    using namespace ::cppu;
    using namespace ::osl;

    //=======================================================================================
    //= OProviderFactory
    //=======================================================================================
    typedef ::cppu::WeakImplHelper1<XEventListener> XEventListener_BASE;
    class ODisposingListener : public XEventListener_BASE
    {
        OProviderFactory& m_aFactory;
    public:
        ODisposingListener(OProviderFactory& _aFactory):
            m_aFactory(_aFactory){}

        virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw()
            {
                m_aFactory.disposing(rEvt);
            }
        ~ODisposingListener()
            {
                volatile int dummy = 0;
            }

    };
    //---------------------------------------------------------------------------------------

    //=======================================================================================
    //= OProviderFactory
    //=======================================================================================
    //---------------------------------------------------------------------------------------
    OProviderFactory::OProviderFactory(const Reference< XMultiServiceFactory >& _rxORB, ProviderInstantiation _pObjectCreator)
        :m_pObjectCreator(_pObjectCreator)
        ,m_xORB(_rxORB)
        ,m_pPureSettings(NULL)
    {
        ODisposingListener *pListener = new ODisposingListener(*this);
        m_xEventListener = pListener;

        Reference<com::sun::star::lang::XComponent> xComponent(_rxORB, UNO_QUERY);
        if (xComponent.is())
        {
            xComponent->addEventListener(m_xEventListener);
            // CFG_TRACE_INFO("insert disposeListener.");
        }
    }

//---------------------------------------------------------------------------------------
    OProviderFactory::~OProviderFactory()
    {
        delete m_pPureSettings;

        Reference<com::sun::star::lang::XComponent> xComponent(m_xORB, UNO_QUERY);
        if (xComponent.is())
        {
            xComponent->removeEventListener(m_xEventListener);
        }
        xComponent = xComponent.query(m_xDefaultProvider);
        if (xComponent.is())
        {
            xComponent->removeEventListener(m_xEventListener);
        }
    }

    //---------------------------------------------------------------------------------------
    void OProviderFactory::ensureBootstrapSettings()
    {
        if (!m_pPureSettings)
            m_pPureSettings = new BootstrapSettings();
    }

    //---------------------------------------------------------------------------------------
    static bool checkForOptions(const ConnectionSettings& _rSettings)
    {
        return  _rSettings.hasLocale()          ||
                _rSettings.hasAsyncSetting();
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::implGetProvider(const ConnectionSettings& _rSettings, sal_Bool _bCanReuse)
    {
        // the providers for the given session type
        UserSpecificProviders& rProviders = m_aProviders[_rSettings.getSessionType()];

        // the user to retrieve the provider for
        ::rtl::OUString sUser;
        if (_rSettings.hasUser())
            sUser = _rSettings.getUser();

        if (checkForOptions(_rSettings))
            _bCanReuse = false;

        Reference< XInterface > xReturn;
        if (_bCanReuse)
        {
            UserSpecificProvidersIterator aExistentProvider = rProviders.find(sUser);
            if (rProviders.end() != aExistentProvider)
            {
                // should check for differing parameters here
                xReturn = aExistentProvider->second;
            }
        }

        // #78409
        // if a provider is queried with a password, we always create a new instance for it,
        // as don't wan't to remember the passwords for the user.

        if (!xReturn.is())
        {
            // create and connect the provider (may still throw exceptions)
            xReturn = (*m_pObjectCreator)(m_xORB, _rSettings);

            // check for success
            if (!xReturn.is())
            {
                OSL_ENSURE(false, "Object creator could not create provider, but returned NULL instead of throwing an exception");
                sal_Char const sCannotCreate[] = "Cannot create ConfigurationProvider. Unknown backend or factory error.";
                // should become CannotLoadConfigurationException
                throw uno::Exception( OUString::createFromAscii(sCannotCreate), *this );
            }

            // remember it for later usage
            if (_bCanReuse)
                rProviders[sUser] = xReturn;
        }

        return xReturn;
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::implCreateProviderWithSettings(const ConnectionSettings& _rSettings, bool _bRequiresBootstrap, bool _bCanReuse)
    {
        try
        {
            return implGetProvider(_rSettings, _bCanReuse);
        }
        catch(uno::Exception& e)
        {
            if (_bRequiresBootstrap)
            {
                OSL_ASSERT(m_pPureSettings);
                raiseBootstrapException(*m_pPureSettings, *this);

                OSL_ASSERT(m_pPureSettings->status == BOOTSTRAP_DATA_OK);
            }

            sal_Char const sConnectionFailure[] = "Cannot open Configuration: ";
            OUString const sFailure = OUString::createFromAscii(sConnectionFailure);
            e.Message = sFailure.concat(e.Message);
            throw;
        }
    }

    //---------------------------------------------------------------------------------------
    void OProviderFactory::ensureDefaultProvider()
    {
        if (m_xDefaultProvider.is())
            return;

        ensureBootstrapSettings();

        m_xDefaultProvider = implCreateProviderWithSettings(m_pPureSettings->settings,true,true);

        // register disposing listener
        Reference<com::sun::star::lang::XComponent> xComponent(m_xDefaultProvider, UNO_QUERY);
        if (xComponent.is())
        {
            xComponent->addEventListener(m_xEventListener);
        }
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::createProvider()
    {
        MutexGuard aGuard(m_aMutex);
        ensureDefaultProvider();
        return m_xDefaultProvider;
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::createProviderWithArguments(const Sequence< Any >& _rArguments)
    {
        ConnectionSettings aSettings(_rArguments);
        return createProviderWithSettings( aSettings );
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::createProviderWithSettings(const ConnectionSettings& _rSettings)
    {
        MutexGuard aGuard(m_aMutex);

        ConnectionSettings aThisRoundSettings(_rSettings);

        // use bootstrap data if necessary
        bool bUseBootstrapData = !aThisRoundSettings.isComplete();

        // detect a plugin session. Can be specified only as argument
        sal_Bool bIsPluginSession = aThisRoundSettings.isPlugin();

        if (bIsPluginSession)
        {
            OSL_ENSURE(!aThisRoundSettings.isSourcePathValid(),"Invalid Argument: No explicit source path should be specified for plugin session");
            bUseBootstrapData = true;
        }

        // use bootstrap data if necessary
        if (bUseBootstrapData)
        {
            ensureBootstrapSettings();

            ConnectionSettings aMergedSettings = m_pPureSettings->settings;
            aMergedSettings.mergeOverrides(aThisRoundSettings);
            aMergedSettings.swap(aThisRoundSettings);
        }

        // if we have a plugin session, translate the session type into the one appliable.
        if (bIsPluginSession)
        {
            // try to create (or share) a local-session provider

            // For a plugin-local session, we need a valid update directory.
            // (We can't just rely on the session to fail if it is created with a valid source directory and an
            // invalid update directory. In such a scenario it will succeed to open, but not to update.)
            if (!m_pPureSettings->settings.isLocalSession())
            {
                const OUString sLocalSessionIdentifier = OUString::createFromAscii(LOCAL_SESSION_IDENTIFIER);

                // (We can't just rely on the session to fail if it is created with a valid source directory and an
                // invalid update directory. In such a scenario it will succeed to open, but not to update.)
                if (aThisRoundSettings.isComplete(sLocalSessionIdentifier) &&
                    aThisRoundSettings.isUpdatePathValid())
                try
                {
                    aThisRoundSettings.setSessionType(sLocalSessionIdentifier, Settings::SO_ADJUSTMENT);
                    return implGetProvider(aThisRoundSettings,true);
                }
                catch(Exception&)
                {
                    // allowed. The creation of the local provider may fail.
                }
            }
            // did not create the local session

            // -> create the original one
            if (m_pPureSettings->settings.isSessionTypeKnown())
            {
                OUString sOriginalType = m_pPureSettings->settings.getSessionType();
                aThisRoundSettings.setSessionType(sOriginalType, Settings::SO_ADJUSTMENT);
            }
            else
            {
                OUString const sPortalSessionIdentifier = OUString::createFromAscii(PORTAL_SESSION_IDENTIFIER);
                aThisRoundSettings.setSessionType(sPortalSessionIdentifier, Settings::SO_ADJUSTMENT);
            }
        }

        aThisRoundSettings.validate();
        OSL_ENSURE(aThisRoundSettings.isComplete(), "Incomplete Data for creating a ConfigurationProvider");

        Reference< XInterface > xProvider =
            implCreateProviderWithSettings( aThisRoundSettings,bUseBootstrapData,
                                            !aThisRoundSettings.hasPassword() );

        return xProvider;
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > SAL_CALL OProviderFactory::createInstance(  ) throw(Exception, RuntimeException)
    {
        // default provider
        return createProvider();
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > SAL_CALL OProviderFactory::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw(Exception, RuntimeException)
    {
        return createProviderWithArguments(_rArguments);
    }

    //=======================================================================================
    Reference< XSingleServiceFactory > SAL_CALL createProviderFactory(
            const Reference< XMultiServiceFactory > & rServiceManager,
            const OUString & rComponentName,
            ProviderInstantiation pCreateFunction,
            const Sequence< OUString > & rServiceNames
        )
    {
        return new OProviderFactory(rServiceManager, pCreateFunction);
    }

    void OProviderFactory::disposing(com::sun::star::lang::EventObject const& _rEvt) throw()
    {
        MutexGuard aGuard(m_aMutex);
        if (_rEvt.Source == m_xORB)
        {
            Reference<com::sun::star::lang::XComponent> xComponent(m_xDefaultProvider, UNO_QUERY);
            if (xComponent.is())
            {
                xComponent->removeEventListener(m_xEventListener);
            }
            m_xORB = NULL;
            m_xDefaultProvider = NULL;
        }
        else if (_rEvt.Source == m_xDefaultProvider)
        {
            m_xDefaultProvider = NULL;
        }
        else
            OSL_ENSURE(sal_False, "unknown object disposed.");
    }

//........................................................................
}   // namespace configmgr
//........................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.8  2001/04/03 16:33:58  jb
 *  Local AdministrationProvider now mapped to Setup-session
 *
 *  Revision 1.7  2001/03/21 12:15:40  jl
 *  OSL_ENSHURE replaced by OSL_ENSURE
 *
 *  Revision 1.6  2001/01/26 07:54:21  lla
 *  #82734# disposing with lasy writing necessary
 *
 *  Revision 1.5  2000/12/07 16:46:12  dg
 *  #81469# incomplete adjustments to portal environment fixed
 *
 *  Revision 1.4  2000/12/07 13:56:21  tlx
 *  #81469#
 *
 *  Revision 1.3  2000/12/03 17:12:52  dg
 *  #81164# stdio missing
 *
 *  Revision 1.2  2000/12/03 11:52:13  dg
 *  #81164# invalid provider instantiation
 *
 *  Revision 1.1  2000/12/01 13:53:17  fs
 *  initial checkin - afctory for configuration provider(s)
 *
 *
 *  Revision 1.0 30.11.00 19:05:35  fs
 ************************************************************************/

<commit_msg>#81412# Erroneous handling of default provider<commit_after>/*************************************************************************
 *
 *  $RCSfile: providerfactory.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: jb $ $Date: 2001-05-22 07:42:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include <stdio.h>
#ifndef _CONFIGMGR_PROVIDER_FACTORY_HXX_
#include "providerfactory.hxx"
#endif

#ifndef _UNO_LBNAMES_H_
#include <uno/lbnames.h>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "confapifactory.hxx"
#endif
#ifndef CONFIGMGR_API_SVCCOMPONENT_HXX_
#include "confsvccomponent.hxx"
#endif
#ifndef CONFIGMGR_BOOTSTRAP_HXX_
#include "bootstrap.hxx"
#endif

// #include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/lang/XComponent.hpp>

#define THISREF() static_cast< ::cppu::OWeakObject* >(this)

//........................................................................
namespace configmgr
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;
    using namespace ::cppu;
    using namespace ::osl;

    //=======================================================================================
    //= OProviderFactory
    //=======================================================================================
    typedef ::cppu::WeakImplHelper1<XEventListener> XEventListener_BASE;
    class ODisposingListener : public XEventListener_BASE
    {
        OProviderFactory& m_aFactory;
    public:
        ODisposingListener(OProviderFactory& _aFactory):
            m_aFactory(_aFactory){}

        virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw()
            {
                m_aFactory.disposing(rEvt);
            }
        ~ODisposingListener()
            {
                volatile int dummy = 0;
            }

    };
    //---------------------------------------------------------------------------------------

    //=======================================================================================
    //= OProviderFactory
    //=======================================================================================
    //---------------------------------------------------------------------------------------
    OProviderFactory::OProviderFactory(const Reference< XMultiServiceFactory >& _rxORB, ProviderInstantiation _pObjectCreator)
        :m_pObjectCreator(_pObjectCreator)
        ,m_xORB(_rxORB)
        ,m_pPureSettings(NULL)
    {
        ODisposingListener *pListener = new ODisposingListener(*this);
        m_xEventListener = pListener;

        Reference<com::sun::star::lang::XComponent> xComponent(_rxORB, UNO_QUERY);
        if (xComponent.is())
        {
            xComponent->addEventListener(m_xEventListener);
            // CFG_TRACE_INFO("insert disposeListener.");
        }
    }

//---------------------------------------------------------------------------------------
    OProviderFactory::~OProviderFactory()
    {
        delete m_pPureSettings;

        Reference<com::sun::star::lang::XComponent> xComponent(m_xORB, UNO_QUERY);
        if (xComponent.is())
        {
            xComponent->removeEventListener(m_xEventListener);
        }
        xComponent = xComponent.query(m_xDefaultProvider);
        if (xComponent.is())
        {
            xComponent->removeEventListener(m_xEventListener);
        }
    }

    //---------------------------------------------------------------------------------------
    void OProviderFactory::ensureBootstrapSettings()
    {
        if (!m_pPureSettings)
            m_pPureSettings = new BootstrapSettings();
    }

    //---------------------------------------------------------------------------------------
    static bool checkForOptions(const ConnectionSettings& _rSettings)
    {
        return  _rSettings.hasLocale()          ||
                _rSettings.hasAsyncSetting();
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::implGetProvider(const ConnectionSettings& _rSettings, sal_Bool _bCanReuse)
    {
        // the providers for the given session type
        UserSpecificProviders& rProviders = m_aProviders[_rSettings.getSessionType()];

        // the user to retrieve the provider for
        ::rtl::OUString sUser;
        if (_rSettings.hasUser())
            sUser = _rSettings.getUser();

        if (checkForOptions(_rSettings))
            _bCanReuse = false;

        Reference< XInterface > xReturn;
        if (_bCanReuse)
        {
            UserSpecificProvidersIterator aExistentProvider = rProviders.find(sUser);
            if (rProviders.end() != aExistentProvider)
            {
                // should check for differing parameters here
                xReturn = aExistentProvider->second;
            }
        }

        // #78409
        // if a provider is queried with a password, we always create a new instance for it,
        // as don't wan't to remember the passwords for the user.

        if (!xReturn.is())
        {
            // create and connect the provider (may still throw exceptions)
            xReturn = (*m_pObjectCreator)(m_xORB, _rSettings);

            // check for success
            if (!xReturn.is())
            {
                OSL_ENSURE(false, "Object creator could not create provider, but returned NULL instead of throwing an exception");
                sal_Char const sCannotCreate[] = "Cannot create ConfigurationProvider. Unknown backend or factory error.";
                // should become CannotLoadConfigurationException
                throw uno::Exception( OUString::createFromAscii(sCannotCreate), *this );
            }

            // remember it for later usage
            if (_bCanReuse)
                rProviders[sUser] = xReturn;
        }

        return xReturn;
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::implCreateProviderWithSettings(const ConnectionSettings& _rSettings, bool _bRequiresBootstrap, bool _bCanReuse)
    {
        try
        {
            return implGetProvider(_rSettings, _bCanReuse);
        }
        catch(uno::Exception& e)
        {
            if (_bRequiresBootstrap)
            {
                OSL_ASSERT(m_pPureSettings);
                raiseBootstrapException(*m_pPureSettings, *this);

                OSL_ASSERT(m_pPureSettings->status == BOOTSTRAP_DATA_OK);
            }

            sal_Char const sConnectionFailure[] = "Cannot open Configuration: ";
            OUString const sFailure = OUString::createFromAscii(sConnectionFailure);
            e.Message = sFailure.concat(e.Message);
            throw;
        }
    }

    //---------------------------------------------------------------------------------------
    void OProviderFactory::ensureDefaultProvider()
    {
        if (m_xDefaultProvider.is())
            return;

        ensureBootstrapSettings();

        ConnectionSettings aThisRoundSettings(m_pPureSettings->settings);

        aThisRoundSettings.validate();
        OSL_ENSURE(aThisRoundSettings.isComplete(), "Incomplete Data for creating a ConfigurationProvider");

        m_xDefaultProvider = implCreateProviderWithSettings(aThisRoundSettings,true,true);

        // register disposing listener
        Reference<com::sun::star::lang::XComponent> xComponent(m_xDefaultProvider, UNO_QUERY);
        if (xComponent.is())
        {
            xComponent->addEventListener(m_xEventListener);
        }
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::createProvider()
    {
        MutexGuard aGuard(m_aMutex);
        ensureDefaultProvider();
        return m_xDefaultProvider;
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::createProviderWithArguments(const Sequence< Any >& _rArguments)
    {
        ConnectionSettings aSettings(_rArguments);
        return createProviderWithSettings( aSettings );
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > OProviderFactory::createProviderWithSettings(const ConnectionSettings& _rSettings)
    {
        MutexGuard aGuard(m_aMutex);

        ConnectionSettings aThisRoundSettings(_rSettings);

        // use bootstrap data if necessary
        bool bUseBootstrapData = !aThisRoundSettings.isComplete();

        // detect a plugin session. Can be specified only as argument
        sal_Bool bIsPluginSession = aThisRoundSettings.isPlugin();

        if (bIsPluginSession)
        {
            OSL_ENSURE(!aThisRoundSettings.isSourcePathValid(),"Invalid Argument: No explicit source path should be specified for plugin session");
            bUseBootstrapData = true;
        }

        // use bootstrap data if necessary
        if (bUseBootstrapData)
        {
            ensureBootstrapSettings();

            ConnectionSettings aMergedSettings = m_pPureSettings->settings;
            aMergedSettings.mergeOverrides(aThisRoundSettings);
            aMergedSettings.swap(aThisRoundSettings);
        }

        // if we have a plugin session, translate the session type into the one appliable.
        if (bIsPluginSession)
        {
            // try to create (or share) a local-session provider

            // For a plugin-local session, we need a valid update directory.
            // (We can't just rely on the session to fail if it is created with a valid source directory and an
            // invalid update directory. In such a scenario it will succeed to open, but not to update.)
            if (!m_pPureSettings->settings.isLocalSession())
            {
                const OUString sLocalSessionIdentifier = OUString::createFromAscii(LOCAL_SESSION_IDENTIFIER);

                // (We can't just rely on the session to fail if it is created with a valid source directory and an
                // invalid update directory. In such a scenario it will succeed to open, but not to update.)
                if (aThisRoundSettings.isComplete(sLocalSessionIdentifier) &&
                    aThisRoundSettings.isUpdatePathValid())
                try
                {
                    aThisRoundSettings.setSessionType(sLocalSessionIdentifier, Settings::SO_ADJUSTMENT);
                    return implGetProvider(aThisRoundSettings,true);
                }
                catch(Exception&)
                {
                    // allowed. The creation of the local provider may fail.
                }
            }
            // did not create the local session

            // -> create the original one
            if (m_pPureSettings->settings.isSessionTypeKnown())
            {
                OUString sOriginalType = m_pPureSettings->settings.getSessionType();
                aThisRoundSettings.setSessionType(sOriginalType, Settings::SO_ADJUSTMENT);
            }
            else
            {
                OUString const sPortalSessionIdentifier = OUString::createFromAscii(PORTAL_SESSION_IDENTIFIER);
                aThisRoundSettings.setSessionType(sPortalSessionIdentifier, Settings::SO_ADJUSTMENT);
            }
        }

        aThisRoundSettings.validate();
        OSL_ENSURE(aThisRoundSettings.isComplete(), "Incomplete Data for creating a ConfigurationProvider");

        Reference< XInterface > xProvider =
            implCreateProviderWithSettings( aThisRoundSettings,bUseBootstrapData,
                                            !aThisRoundSettings.hasPassword() );

        return xProvider;
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > SAL_CALL OProviderFactory::createInstance(  ) throw(Exception, RuntimeException)
    {
        // default provider
        return createProvider();
    }

    //---------------------------------------------------------------------------------------
    Reference< XInterface > SAL_CALL OProviderFactory::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw(Exception, RuntimeException)
    {
        return createProviderWithArguments(_rArguments);
    }

    //=======================================================================================
    Reference< XSingleServiceFactory > SAL_CALL createProviderFactory(
            const Reference< XMultiServiceFactory > & rServiceManager,
            const OUString & rComponentName,
            ProviderInstantiation pCreateFunction,
            const Sequence< OUString > & rServiceNames
        )
    {
        return new OProviderFactory(rServiceManager, pCreateFunction);
    }

    void OProviderFactory::disposing(com::sun::star::lang::EventObject const& _rEvt) throw()
    {
        MutexGuard aGuard(m_aMutex);
        if (_rEvt.Source == m_xORB)
        {
            Reference<com::sun::star::lang::XComponent> xComponent(m_xDefaultProvider, UNO_QUERY);
            if (xComponent.is())
            {
                xComponent->removeEventListener(m_xEventListener);
            }
            m_xORB = NULL;
            m_xDefaultProvider = NULL;
        }
        else if (_rEvt.Source == m_xDefaultProvider)
        {
            m_xDefaultProvider = NULL;
        }
        else
            OSL_ENSURE(sal_False, "unknown object disposed.");
    }

//........................................................................
}   // namespace configmgr
//........................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.9  2001/05/18 16:16:52  jb
 *  #81412# Cleaned up bootstrap settings handling; Added recognition of bootstrap errors
 *
 *  Revision 1.8  2001/04/03 16:33:58  jb
 *  Local AdministrationProvider now mapped to Setup-session
 *
 *  Revision 1.7  2001/03/21 12:15:40  jl
 *  OSL_ENSHURE replaced by OSL_ENSURE
 *
 *  Revision 1.6  2001/01/26 07:54:21  lla
 *  #82734# disposing with lasy writing necessary
 *
 *  Revision 1.5  2000/12/07 16:46:12  dg
 *  #81469# incomplete adjustments to portal environment fixed
 *
 *  Revision 1.4  2000/12/07 13:56:21  tlx
 *  #81469#
 *
 *  Revision 1.3  2000/12/03 17:12:52  dg
 *  #81164# stdio missing
 *
 *  Revision 1.2  2000/12/03 11:52:13  dg
 *  #81164# invalid provider instantiation
 *
 *  Revision 1.1  2000/12/01 13:53:17  fs
 *  initial checkin - afctory for configuration provider(s)
 *
 *
 *  Revision 1.0 30.11.00 19:05:35  fs
 ************************************************************************/

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: PColumn.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: oj $ $Date: 2002-07-05 06:58:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_PCOLUMN_HXX_
#define _CONNECTIVITY_PCOLUMN_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
#include "connectivity/sdbcx/VColumn.hxx"
#endif

namespace connectivity
{
    namespace parse
    {
        class OParseColumn;

        typedef sdbcx::OColumn OParseColumn_BASE;
        typedef ::comphelper::OIdPropertyArrayUsageHelper<OParseColumn> OParseColumn_PROP;

        class OParseColumn :    public OParseColumn_BASE,
                                public OParseColumn_PROP
        {
            ::rtl::OUString m_aRealName;
            ::rtl::OUString m_aTableName;
            sal_Bool        m_bFunction;
            sal_Bool        m_bDbasePrecisionChanged;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper( sal_Int32 _nId) const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OParseColumn();
        public:
            OParseColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase);
            OParseColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase);

            virtual void construct();

            void setRealName(const ::rtl::OUString& _rName)  { m_aRealName  = _rName; }
            void setTableName(const ::rtl::OUString& _rName) { m_aTableName = _rName; }
            void setFunction(sal_Bool _bFunction)            { m_bFunction  = _bFunction; }
            void setDbasePrecisionChanged(sal_Bool _bDbasePrecisionChanged) { m_bDbasePrecisionChanged = _bDbasePrecisionChanged; }

            ::rtl::OUString getRealName() const { return  m_aRealName; }
            ::rtl::OUString getTableName() const { return  m_aTableName; }
            sal_Bool        getFunction() const { return  m_bFunction; }
            sal_Bool        getDbasePrecisionChanged()  const { return  m_bDbasePrecisionChanged; }
        };
    }
}

#endif //_CONNECTIVITY_PCOLUMN_HXX_

<commit_msg>INTEGRATION: CWS qrycomp (1.9.126); FILE MERGED 2003/10/30 14:13:31 oj 1.9.126.1: #i21791# changes for the querycomposer<commit_after>/*************************************************************************
 *
 *  $RCSfile: PColumn.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: vg $ $Date: 2003-12-16 12:26:58 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_PCOLUMN_HXX_
#define _CONNECTIVITY_PCOLUMN_HXX_

#ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_
#include "connectivity/sdbcx/VColumn.hxx"
#endif

namespace connectivity
{
    namespace parse
    {
        class OParseColumn;

        typedef sdbcx::OColumn OParseColumn_BASE;
        typedef ::comphelper::OIdPropertyArrayUsageHelper<OParseColumn> OParseColumn_PROP;

        class OParseColumn :    public OParseColumn_BASE,
                                public OParseColumn_PROP
        {
            ::rtl::OUString m_aRealName;
            ::rtl::OUString m_aTableName;
            sal_Bool        m_bFunction;
            sal_Bool        m_bDbasePrecisionChanged;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper( sal_Int32 _nId) const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OParseColumn();
        public:
            OParseColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase);
            OParseColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase);

            virtual void construct();

            void setRealName(const ::rtl::OUString& _rName)  { m_aRealName  = _rName; }
            void setTableName(const ::rtl::OUString& _rName) { m_aTableName = _rName; }
            void setFunction(sal_Bool _bFunction)            { m_bFunction  = _bFunction; }
            void setDbasePrecisionChanged(sal_Bool _bDbasePrecisionChanged) { m_bDbasePrecisionChanged = _bDbasePrecisionChanged; }

            ::rtl::OUString getRealName() const { return  m_aRealName; }
            ::rtl::OUString getTableName() const { return  m_aTableName; }
            sal_Bool        getFunction() const { return  m_bFunction; }
            sal_Bool        getDbasePrecisionChanged()  const { return  m_bDbasePrecisionChanged; }
        };

        class OOrderColumn;

        typedef sdbcx::OColumn OOrderColumn_BASE;
        typedef ::comphelper::OIdPropertyArrayUsageHelper<OOrderColumn> OOrderColumn_PROP;

        class OOrderColumn :    public OOrderColumn_BASE,
                                public OOrderColumn_PROP
        {
            sal_Bool        m_bAscending;
            sal_Bool        m_bOrder;
        protected:
            virtual ::cppu::IPropertyArrayHelper* createArrayHelper( sal_Int32 _nId) const;
            virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

            virtual ~OOrderColumn();
        public:
            OOrderColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _xColumn,sal_Bool _bCase,sal_Bool _bAscending);
            OOrderColumn(const ::rtl::OUString& _Name,
                    const ::rtl::OUString& _TypeName,
                    const ::rtl::OUString& _DefaultValue,
                    sal_Int32       _IsNullable,
                    sal_Int32       _Precision,
                    sal_Int32       _Scale,
                    sal_Int32       _Type,
                    sal_Bool        _IsAutoIncrement,
                    sal_Bool        _IsCurrency,
                    sal_Bool        _bCase
                    ,sal_Bool _bAscending);

            virtual void construct();

            virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
        };
    }
}

#endif //_CONNECTIVITY_PCOLUMN_HXX_

<|endoftext|>