| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "precompiled_stoc.hxx" |
| #include "sal/config.h" |
| |
| #include <cstddef> |
| #include <cstdlib> |
| #include <map> |
| #include <vector> |
| |
| #include "boost/noncopyable.hpp" |
| #include "com/sun/star/container/NoSuchElementException.hpp" |
| #include "com/sun/star/registry/InvalidRegistryException.hpp" |
| #include "com/sun/star/registry/XRegistryKey.hpp" |
| #include "com/sun/star/uno/Reference.hxx" |
| #include "com/sun/star/uno/XInterface.hpp" |
| #include "cppuhelper/implbase1.hxx" |
| #include "osl/diagnose.h" |
| #include "rtl/malformeduriexception.hxx" |
| #include "rtl/ref.hxx" |
| #include "rtl/string.h" |
| #include "rtl/uri.hxx" |
| #include "rtl/ustrbuf.hxx" |
| #include "rtl/ustring.h" |
| #include "rtl/ustring.hxx" |
| #include "salhelper/simplereferenceobject.hxx" |
| #include "xmlreader/span.hxx" |
| #include "xmlreader/xmlreader.hxx" |
| |
| #include "textualservices.hxx" |
| |
| namespace stoc { namespace simpleregistry { |
| |
| namespace { |
| |
| namespace css = com::sun::star; |
| |
| struct Implementation { |
| rtl::OUString uri; |
| rtl::OUString loader; |
| std::vector< rtl::OUString > services; |
| std::vector< rtl::OUString > singletons; |
| }; |
| |
| typedef std::map< rtl::OUString, Implementation > Implementations; |
| |
| typedef std::map< rtl::OUString, std::vector< rtl::OUString > > |
| ImplementationMap; |
| |
| } |
| |
| class Data: public salhelper::SimpleReferenceObject, private boost::noncopyable |
| { |
| public: |
| Implementations implementations; |
| ImplementationMap services; |
| ImplementationMap singletons; |
| }; |
| |
| namespace { |
| |
| class Parser: private boost::noncopyable { |
| public: |
| Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data); |
| |
| private: |
| void handleComponent(); |
| |
| void handleImplementation(); |
| |
| void handleService(); |
| |
| void handleSingleton(); |
| |
| rtl::OUString getNameAttribute(); |
| |
| xmlreader::XmlReader reader_; |
| rtl::Reference< Data > data_; |
| rtl::OUString attrUri_; |
| rtl::OUString attrLoader_; |
| rtl::OUString attrImplementation_; |
| }; |
| |
| Parser::Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data): |
| reader_(uri), data_(data) |
| { |
| OSL_ASSERT(data.is()); |
| int ucNsId = reader_.registerNamespaceIri( |
| xmlreader::Span( |
| RTL_CONSTASCII_STRINGPARAM( |
| "http://openoffice.org/2010/uno-components"))); |
| enum State { |
| STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL, |
| STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON }; |
| for (State state = STATE_BEGIN;;) { |
| xmlreader::Span name; |
| int nsId; |
| xmlreader::XmlReader::Result res = reader_.nextItem( |
| xmlreader::XmlReader::TEXT_NONE, &name, &nsId); |
| switch (state) { |
| case STATE_BEGIN: |
| if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("components"))) |
| { |
| state = STATE_COMPONENTS; |
| break; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in outer level"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| case STATE_END: |
| if (res == xmlreader::XmlReader::RESULT_DONE) { |
| return; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in outer level"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| case STATE_COMPONENTS: |
| if (res == xmlreader::XmlReader::RESULT_END) { |
| state = STATE_END; |
| break; |
| } |
| if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("component"))) |
| { |
| handleComponent(); |
| state = STATE_COMPONENT_INITIAL; |
| break; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in <components>"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| case STATE_COMPONENT: |
| if (res == xmlreader::XmlReader::RESULT_END) { |
| state = STATE_COMPONENTS; |
| break; |
| } |
| // fall through |
| case STATE_COMPONENT_INITIAL: |
| if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("implementation"))) |
| { |
| handleImplementation(); |
| state = STATE_IMPLEMENTATION; |
| break; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in <component>"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| case STATE_IMPLEMENTATION: |
| if (res == xmlreader::XmlReader::RESULT_END) { |
| state = STATE_COMPONENT; |
| break; |
| } |
| if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("service"))) |
| { |
| handleService(); |
| state = STATE_SERVICE; |
| break; |
| } |
| if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("singleton"))) |
| { |
| handleSingleton(); |
| state = STATE_SINGLETON; |
| break; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in <implementation>"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| case STATE_SERVICE: |
| if (res == xmlreader::XmlReader::RESULT_END) { |
| state = STATE_IMPLEMENTATION; |
| break; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in <service>"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| case STATE_SINGLETON: |
| if (res == xmlreader::XmlReader::RESULT_END) { |
| state = STATE_IMPLEMENTATION; |
| break; |
| } |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": unexpected item in <service>"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } |
| } |
| |
| void Parser::handleComponent() { |
| attrUri_ = rtl::OUString(); |
| attrLoader_ = rtl::OUString(); |
| xmlreader::Span name; |
| int nsId; |
| while (reader_.nextAttribute(&nsId, &name)) { |
| if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("uri"))) |
| { |
| if (attrUri_.getLength() != 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": <component> has multiple \"uri\" attributes"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| attrUri_ = reader_.getAttributeValue(false).convertFromUtf8(); |
| if (attrUri_.getLength() == 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": <component> has empty \"uri\" attribute"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("loader"))) |
| { |
| if (attrLoader_.getLength() != 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": <component> has multiple \"loader\"" |
| " attributes"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8(); |
| if (attrLoader_.getLength() == 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": <component> has empty \"loader\" attribute"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } else { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": expected <component> attribute \"uri\" or" |
| " \"loader\""))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } |
| if (attrUri_.getLength() == 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": <component> is missing \"uri\" attribute"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| if (attrLoader_.getLength() == 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": <component> is missing \"loader\" attribute"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| try { |
| attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_); |
| } catch (rtl::MalformedUriException & e) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM(": bad \"uri\" attribute: ")) + |
| e.getMessage()), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } |
| |
| void Parser::handleImplementation() { |
| attrImplementation_ = getNameAttribute(); |
| if (data_->implementations.find(attrImplementation_) != |
| data_->implementations.end()) |
| { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": duplicate <implementation name=\"")) + |
| attrImplementation_ + |
| rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\">"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| data_->implementations[attrImplementation_].uri = attrUri_; |
| data_->implementations[attrImplementation_].loader = attrLoader_; |
| } |
| |
| void Parser::handleService() { |
| rtl::OUString name = getNameAttribute(); |
| data_->implementations[attrImplementation_].services.push_back(name); |
| data_->services[name].push_back(attrImplementation_); |
| } |
| |
| void Parser::handleSingleton() { |
| rtl::OUString name = getNameAttribute(); |
| data_->implementations[attrImplementation_].singletons.push_back(name); |
| data_->singletons[name].push_back(attrImplementation_); |
| } |
| |
| rtl::OUString Parser::getNameAttribute() { |
| rtl::OUString attrName; |
| xmlreader::Span name; |
| int nsId; |
| while (reader_.nextAttribute(&nsId, &name)) { |
| if (nsId == xmlreader::XmlReader::NAMESPACE_NONE && |
| name.equals(RTL_CONSTASCII_STRINGPARAM("name"))) |
| { |
| if (attrName.getLength() != 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": element has multiple \"name\" attributes"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| attrName = reader_.getAttributeValue(false).convertFromUtf8(); |
| if (attrName.getLength() == 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": element has empty \"name\" attribute"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } else { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": expected element attribute \"name\""))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } |
| if (attrName.getLength() == 0) { |
| throw css::registry::InvalidRegistryException( |
| (reader_.getUrl() + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| ": element is missing \"name\" attribute"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| return attrName; |
| } |
| |
| rtl::OUString pathToString(std::vector< rtl::OUString > const & path) { |
| rtl::OUStringBuffer buf; |
| for (std::vector< rtl::OUString >::const_iterator i(path.begin()); |
| i != path.end(); ++i) |
| { |
| buf.append(sal_Unicode('/')); |
| buf.append(*i); |
| } |
| if (buf.getLength() == 0) { |
| buf.append(sal_Unicode('/')); |
| } |
| return buf.makeStringAndClear(); |
| } |
| |
| class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > { |
| public: |
| Key( |
| rtl::Reference< Data > const & data, |
| std::vector< rtl::OUString > const & path): |
| data_(data), path_(path) { OSL_ASSERT(data.is()); |
| } |
| |
| private: |
| /* |
| / |
| IMPLEMENTATIONS |
| <implementation> |
| UNO |
| LOCATION utf-8 |
| ACTIVATOR utf-8 |
| SERVICES |
| <service> |
| ... |
| SINGLETONS |
| <singleton> utf-16 |
| ... |
| ... |
| SERVICES |
| <service> utf-8-list |
| ... |
| SINGLETONS |
| <singleton> utf-16 |
| REGISTERED_BY utf-8-list |
| ... |
| */ |
| enum State { |
| STATE_ROOT, STATE_IMPLEMENTATIONS, STATE_IMPLEMENTATION, STATE_UNO, |
| STATE_LOCATION, STATE_ACTIVATOR, STATE_IMPLEMENTATION_SERVICES, |
| STATE_IMPLEMENTATION_SERVICE, STATE_IMPLEMENTATION_SINGLETONS, |
| STATE_IMPLEMENTATION_SINGLETON, STATE_SERVICES, STATE_SERVICE, |
| STATE_SINGLETONS, STATE_SINGLETON, STATE_REGISTEREDBY }; |
| |
| virtual rtl::OUString SAL_CALL getKeyName() |
| throw (css::uno::RuntimeException); |
| |
| virtual sal_Bool SAL_CALL isReadOnly() throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual sal_Bool SAL_CALL isValid() throw(css::uno::RuntimeException); |
| |
| virtual css::registry::RegistryKeyType SAL_CALL getKeyType( |
| rtl::OUString const & rKeyName) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual css::registry::RegistryValueType SAL_CALL getValueType() throw( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual sal_Int32 SAL_CALL getLongValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setLongValue(sal_Int32 value) throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() throw( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setLongListValue( |
| com::sun::star::uno::Sequence< sal_Int32 > const & seqValue) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual rtl::OUString SAL_CALL getAsciiValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setAsciiValue(rtl::OUString const & value) throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue() |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setAsciiListValue( |
| css::uno::Sequence< rtl::OUString > const & seqValue) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual rtl::OUString SAL_CALL getStringValue() throw( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setStringValue(rtl::OUString const & value) throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue() |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setStringListValue( |
| css::uno::Sequence< rtl::OUString > const & seqValue) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL setBinaryValue( |
| css::uno::Sequence< sal_Int8 > const & value) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey( |
| rtl::OUString const & aKeyName) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL |
| createKey(rtl::OUString const & aKeyName) throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL closeKey() throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName) throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual |
| css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > |
| SAL_CALL openKeys() throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames() throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual sal_Bool SAL_CALL createLink( |
| rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName) throw ( |
| css::registry::InvalidRegistryException, css::uno::RuntimeException); |
| |
| virtual rtl::OUString SAL_CALL getLinkTarget( |
| rtl::OUString const & rLinkName) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| virtual rtl::OUString SAL_CALL getResolvedName( |
| rtl::OUString const & aKeyName) |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::uno::RuntimeException); |
| |
| bool find( |
| rtl::OUString const & relative, std::vector< rtl::OUString > * path, |
| State * state, css::registry::RegistryValueType * type) const; |
| |
| css::uno::Sequence< rtl::OUString > getChildren(); |
| |
| rtl::Reference< Data > data_; |
| std::vector< rtl::OUString > path_; |
| }; |
| |
| rtl::OUString Key::getKeyName() throw (css::uno::RuntimeException) { |
| return pathToString(path_); |
| } |
| |
| sal_Bool Key::isReadOnly() |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| return true; |
| } |
| |
| sal_Bool Key::isValid() throw(css::uno::RuntimeException) { |
| return true; |
| } |
| |
| css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| if (!find(rtl::OUString(), 0, 0, 0)) { |
| throw css::registry::InvalidRegistryException( |
| (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown key ")) + |
| rKeyName), |
| static_cast< cppu::OWeakObject * >(this)); |
| } |
| return css::registry::RegistryKeyType_KEY; |
| } |
| |
| css::registry::RegistryValueType Key::getValueType() |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| css::registry::RegistryValueType type = |
| css::registry::RegistryValueType_NOT_DEFINED; |
| OSL_VERIFY(find(rtl::OUString(), 0, 0, &type)); |
| return type; |
| } |
| |
| sal_Int32 Key::getLongValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getLongValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::setLongValue(sal_Int32) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setLongValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| css::uno::Sequence< sal_Int32 > Key::getLongListValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getLongListValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setLongListValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| rtl::OUString Key::getAsciiValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| State state = STATE_ROOT; |
| OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); |
| switch (state) { |
| case STATE_LOCATION: |
| return data_->implementations[path_[1]].uri; |
| case STATE_ACTIVATOR: |
| return data_->implementations[path_[1]].loader; |
| default: |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getAsciiValue: wrong type")), |
| static_cast< OWeakObject * >(this)); |
| } |
| } |
| |
| void Key::setAsciiValue(rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setAsciiValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| css::uno::Sequence< rtl::OUString > Key::getAsciiListValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| State state = STATE_ROOT; |
| OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); |
| std::vector< rtl::OUString > const * list; |
| switch (state) { |
| case STATE_SERVICE: |
| list = &data_->services[path_[1]]; |
| break; |
| case STATE_REGISTEREDBY: |
| list = &data_->singletons[path_[1]]; |
| break; |
| default: |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getAsciiListValue: wrong type")), |
| static_cast< OWeakObject * >(this)); |
| } |
| if (list->size() > SAL_MAX_INT32) { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getAsciiListValue: too large")), |
| static_cast< OWeakObject * >(this)); |
| } |
| css::uno::Sequence< rtl::OUString > seq( |
| static_cast< sal_Int32 >(list->size())); |
| sal_Int32 i = 0; |
| for (std::vector< rtl::OUString >::const_iterator j(list->begin()); |
| j != list->end(); ++j) |
| { |
| seq[i++] = *j; |
| } |
| return seq; |
| } |
| |
| void Key::setAsciiListValue(css::uno::Sequence< rtl::OUString > const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setAsciiListValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| rtl::OUString Key::getStringValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| State state = STATE_ROOT; |
| OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); |
| switch (state) { |
| case STATE_IMPLEMENTATION_SINGLETON: |
| case STATE_SINGLETON: |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getStringValue: does not associate singletons with" |
| " services")), |
| static_cast< OWeakObject * >(this)); |
| default: |
| break; |
| } |
| // default case extracted from switch to avoid erroneous compiler warnings |
| // on Solaris: |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getStringValue: wrong type")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::setStringValue(rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setStringValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| css::uno::Sequence< rtl::OUString > Key::getStringListValue() throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getStringListValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::setStringListValue(css::uno::Sequence< rtl::OUString > const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setStringListValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| css::uno::Sequence< sal_Int8 > Key::getBinaryValue() |
| throw ( |
| css::registry::InvalidRegistryException, |
| css::registry::InvalidValueException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getBinarValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " setBinaryValue not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| css::uno::Reference< css::registry::XRegistryKey > Key::openKey( |
| rtl::OUString const & aKeyName) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| std::vector< rtl::OUString > path; |
| if (!find(aKeyName, &path, 0, 0)) { |
| return css::uno::Reference< css::registry::XRegistryKey >(); |
| } |
| return new Key(data_, path); |
| } |
| |
| css::uno::Reference< css::registry::XRegistryKey > Key::createKey( |
| rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " createKey not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::closeKey() |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| {} |
| |
| void Key::deleteKey(rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " deleteKey not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > |
| Key::openKeys() |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| css::uno::Sequence< rtl::OUString > names(getChildren()); |
| css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > |
| keys(names.getLength()); |
| for (sal_Int32 i = 0; i < keys.getLength(); ++i) { |
| keys[i] = openKey(names[i]); |
| OSL_ASSERT(keys[i].is()); |
| } |
| return keys; |
| } |
| |
| css::uno::Sequence< rtl::OUString > Key::getKeyNames() |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| css::uno::Sequence< rtl::OUString > names(getChildren()); |
| rtl::OUString prefix(pathToString(path_)); |
| prefix += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); |
| for (sal_Int32 i = 0; i < names.getLength(); ++i) { |
| names[i] = prefix + names[i]; |
| } |
| return names; |
| } |
| |
| sal_Bool Key::createLink(rtl::OUString const &, rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " createLink not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| void Key::deleteLink(rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " deleteLink not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| rtl::OUString Key::getLinkTarget(rtl::OUString const &) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| throw css::registry::InvalidRegistryException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual services key" |
| " getLinkTarget not supported")), |
| static_cast< OWeakObject * >(this)); |
| } |
| |
| rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName) |
| throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) |
| { |
| std::vector< rtl::OUString > path; |
| find(aKeyName, &path, 0, 0); |
| return pathToString(path); |
| } |
| |
| bool Key::find( |
| rtl::OUString const & relative, std::vector< rtl::OUString > * path, |
| State * state, css::registry::RegistryValueType * type) const |
| { |
| std::vector< rtl::OUString > p(path_); |
| sal_Int32 i = 0; |
| do { |
| rtl::OUString seg(relative.getToken(0, '/', i)); |
| if (seg.getLength() != 0) { |
| p.push_back(seg); |
| } |
| } while (i >= 0); |
| if (path != 0) { |
| *path = p; |
| } |
| std::size_t const MAX_TRANSITIONS = 4; |
| struct StateInfo { |
| css::registry::RegistryValueType type; |
| std::size_t count; |
| struct { char const * segment; State state; } |
| transitions[MAX_TRANSITIONS]; |
| }; |
| static StateInfo const info[] = { |
| // STATE_ROOT: |
| { css::registry::RegistryValueType_NOT_DEFINED, 3, |
| { { "IMPLEMENTATIONS", STATE_IMPLEMENTATIONS }, |
| { "SERVICES", STATE_SERVICES }, |
| { "SINGLETONS", STATE_SINGLETONS } } }, |
| // STATE_IMPLEMENTATIONS: |
| { css::registry::RegistryValueType_NOT_DEFINED, 1, |
| { { 0, STATE_IMPLEMENTATION } } }, |
| // STATE_IMPLEMENTATION: |
| { css::registry::RegistryValueType_NOT_DEFINED, 1, |
| { { "UNO", STATE_UNO } } }, |
| // STATE_UNO: |
| { css::registry::RegistryValueType_NOT_DEFINED, 4, |
| { { "LOCATION", STATE_LOCATION }, |
| { "ACTIVATOR", STATE_ACTIVATOR }, |
| { "SERVICES", STATE_IMPLEMENTATION_SERVICES }, |
| { "SINGLETONS", STATE_IMPLEMENTATION_SINGLETONS } } }, |
| // STATE_LOCATION: |
| { css::registry::RegistryValueType_ASCII, 0, {} }, |
| // STATE_ACTIVATOR: |
| { css::registry::RegistryValueType_ASCII, 0, {} }, |
| // STATE_IMPLEMENTATION_SERVICES: |
| { css::registry::RegistryValueType_NOT_DEFINED, 1, |
| { { 0, STATE_IMPLEMENTATION_SERVICE } } }, |
| // STATE_IMPLEMENTATION_SERVICE: |
| { css::registry::RegistryValueType_NOT_DEFINED, 0, {} }, |
| // STATE_IMPLEMENTATION_SINGLETONS: |
| { css::registry::RegistryValueType_NOT_DEFINED, 1, |
| { { 0, STATE_IMPLEMENTATION_SINGLETON } } }, |
| // STATE_IMPLEMENTATION_SINGLETON: |
| { css::registry::RegistryValueType_STRING, 0, {} }, |
| // STATE_SERVICES: |
| { css::registry::RegistryValueType_NOT_DEFINED, 1, |
| { { 0, STATE_SERVICE } } }, |
| // STATE_SERVICE: |
| { css::registry::RegistryValueType_ASCIILIST, 0, {} }, |
| // STATE_SINGLETONS: |
| { css::registry::RegistryValueType_NOT_DEFINED, 1, |
| { { 0, STATE_SINGLETON } } }, |
| // STATE_SINGLETON: |
| { css::registry::RegistryValueType_STRING, 1, |
| { { "REGISTERED_BY", STATE_REGISTEREDBY } } }, |
| // STATE_REGISTEREDBY: |
| { css::registry::RegistryValueType_ASCIILIST, 0, {} } }; |
| State s = STATE_ROOT; |
| for (std::vector< rtl::OUString >::iterator j(p.begin()); j != p.end(); ++j) |
| { |
| bool found = false; |
| for (std::size_t k = 0; k < info[s].count; ++k) { |
| if (info[s].transitions[k].segment == 0) { |
| switch (info[s].transitions[k].state) { |
| case STATE_IMPLEMENTATION: |
| found = data_->implementations.find(*j) != |
| data_->implementations.end(); |
| break; |
| case STATE_IMPLEMENTATION_SERVICE: |
| case STATE_IMPLEMENTATION_SINGLETON: |
| found = true; //TODO |
| break; |
| case STATE_SERVICE: |
| found = data_->services.find(*j) != data_->services.end(); |
| break; |
| case STATE_SINGLETON: |
| found = data_->singletons.find(*j) != |
| data_->singletons.end(); |
| break; |
| default: |
| std::abort(); // this cannot happen |
| } |
| } else { |
| found = j->equalsAscii(info[s].transitions[k].segment); |
| } |
| if (found) { |
| s = info[s].transitions[k].state; |
| break; |
| } |
| } |
| if (!found) { |
| return false; |
| } |
| } |
| if (state != 0) { |
| *state = s; |
| } |
| if (type != 0) { |
| *type = info[s].type; |
| } |
| return true; |
| } |
| |
| css::uno::Sequence< rtl::OUString > Key::getChildren() { |
| State state = STATE_ROOT; |
| OSL_VERIFY(find(rtl::OUString(), 0, &state, 0)); |
| switch (state) { |
| default: |
| std::abort(); // this cannot happen |
| // pseudo-fall-through to avoid warnings on MSC |
| case STATE_ROOT: |
| { |
| css::uno::Sequence< rtl::OUString > seq(3); |
| seq[0] = rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS")); |
| seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES")); |
| seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS")); |
| return seq; |
| } |
| case STATE_IMPLEMENTATIONS: |
| { |
| if (data_->implementations.size() > SAL_MAX_INT32) { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual" |
| " services key openKeys: too large")), |
| static_cast< OWeakObject * >(this)); |
| } |
| css::uno::Sequence< rtl::OUString > seq( |
| static_cast< sal_Int32 >(data_->implementations.size())); |
| sal_Int32 i = 0; |
| for (Implementations::iterator j(data_->implementations.begin()); |
| j != data_->implementations.end(); ++j) |
| { |
| seq[i++] = j->first; |
| } |
| return seq; |
| } |
| case STATE_UNO: |
| { |
| css::uno::Sequence< rtl::OUString > seq(4); |
| seq[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCATION")); |
| seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ACTIVATOR")); |
| seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES")); |
| seq[3] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS")); |
| return seq; |
| } |
| case STATE_LOCATION: |
| case STATE_ACTIVATOR: |
| case STATE_IMPLEMENTATION_SERVICE: |
| case STATE_IMPLEMENTATION_SINGLETON: |
| case STATE_SERVICE: |
| case STATE_REGISTEREDBY: |
| return css::uno::Sequence< rtl::OUString >(); |
| case STATE_IMPLEMENTATION_SERVICES: |
| { |
| if (data_->implementations[path_[1]].services.size() > |
| SAL_MAX_INT32) |
| { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual" |
| " services key openKeys: too large")), |
| static_cast< OWeakObject * >(this)); |
| } |
| css::uno::Sequence< rtl::OUString > seq( |
| static_cast< sal_Int32 >( |
| data_->implementations[path_[1]].services.size())); |
| sal_Int32 i = 0; |
| for (std::vector< rtl::OUString >::iterator j( |
| data_->implementations[path_[1]].services.begin()); |
| j != data_->implementations[path_[1]].services.end(); ++j) |
| { |
| seq[i++] = *j; |
| } |
| return seq; |
| } |
| case STATE_IMPLEMENTATION_SINGLETONS: |
| { |
| if (data_->implementations[path_[1]].singletons.size() > |
| SAL_MAX_INT32) |
| { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual" |
| " services key openKeys: too large")), |
| static_cast< OWeakObject * >(this)); |
| } |
| css::uno::Sequence< rtl::OUString > seq( |
| static_cast< sal_Int32 >( |
| data_->implementations[path_[1]].singletons.size())); |
| sal_Int32 i = 0; |
| for (std::vector< rtl::OUString >::iterator j( |
| data_->implementations[path_[1]].singletons.begin()); |
| j != data_->implementations[path_[1]].singletons.end(); ++j) |
| { |
| seq[i++] = *j; |
| } |
| return seq; |
| } |
| case STATE_SERVICES: |
| { |
| if (data_->services.size() > SAL_MAX_INT32) { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual" |
| " services key openKeys: too large")), |
| static_cast< OWeakObject * >(this)); |
| } |
| css::uno::Sequence< rtl::OUString > seq( |
| static_cast< sal_Int32 >(data_->services.size())); |
| sal_Int32 i = 0; |
| for (ImplementationMap::iterator j(data_->services.begin()); |
| j != data_->services.end(); ++j) |
| { |
| seq[i++] = j->first; |
| } |
| return seq; |
| } |
| case STATE_SINGLETONS: |
| { |
| if (data_->singletons.size() > SAL_MAX_INT32) { |
| throw css::registry::InvalidValueException( |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.registry.SimpleRegistry textual" |
| " services key openKeys: too large")), |
| static_cast< OWeakObject * >(this)); |
| } |
| css::uno::Sequence< rtl::OUString > seq( |
| static_cast< sal_Int32 >(data_->singletons.size())); |
| sal_Int32 i = 0; |
| for (ImplementationMap::iterator j(data_->singletons.begin()); |
| j != data_->singletons.end(); ++j) |
| { |
| seq[i++] = j->first; |
| } |
| return seq; |
| } |
| case STATE_SINGLETON: |
| { |
| css::uno::Sequence< rtl::OUString > seq(1); |
| seq[0] = rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM("REGISTERED_BY")); |
| return seq; |
| } |
| } |
| } |
| |
| } |
| |
| TextualServices::TextualServices(rtl::OUString const & uri): |
| uri_(uri), data_(new Data) |
| { |
| try { |
| Parser(uri, data_); |
| } catch (css::container::NoSuchElementException &) { |
| throw css::registry::InvalidRegistryException( |
| (uri + |
| rtl::OUString( |
| RTL_CONSTASCII_USTRINGPARAM(": no such file"))), |
| css::uno::Reference< css::uno::XInterface >()); |
| } |
| } |
| |
| TextualServices::~TextualServices() {} |
| |
| css::uno::Reference< css::registry::XRegistryKey > TextualServices::getRootKey() |
| { |
| return new Key(data_, std::vector< rtl::OUString >()); |
| } |
| |
| } } |