1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cfgregistrykey.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
33 #include "cfgregistrykey.hxx"
34 #include "datalock.hxx"
35 #include "typeconverter.hxx"
36 #include <osl/diagnose.h>
37 #include <cppuhelper/extract.hxx>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <com/sun/star/container/XChild.hpp>
41 #include <com/sun/star/container/XHierarchicalName.hpp>
42 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
43 #include <com/sun/star/lang/XServiceInfo.hpp>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <com/sun/star/beans/Property.hpp>
46 #include <com/sun/star/beans/PropertyAttribute.hpp>
47 #include <com/sun/star/beans/XProperty.hpp>
48 #include <com/sun/star/util/XStringEscape.hpp>
49 #include <com/sun/star/uno/Sequence.hxx>
50 #include <typelib/typedescription.hxx>
54 #define THISREF() static_cast< ::cppu::OWeakObject* >(this)
55 #define UNISTRING(c) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(c) )
57 //..........................................................................
60 //..........................................................................
62 //--------------------------------------------------------------------------
65 com::sun::star::uno::Type
getBinaryDataType()
67 com::sun::star::uno::Sequence
<sal_Int8
> const * const p
= 0;
68 return ::getCppuType(p
);
71 bool isAscii(sal_Unicode ch
)
73 return 0 < ch
&& ch
< 128;
76 bool isAscii(sal_Unicode
const * ps
, sal_Int32 nLen
)
78 for (int i
= 0; i
< nLen
; ++i
)
79 if ( !isAscii( ps
[i
] ) )
84 bool isAscii(rtl::OUString
const& str
)
86 return isAscii(str
.getStr(),str
.getLength());
89 bool isAscii(com::sun::star::uno::Sequence
< rtl::OUString
> const& strList
)
91 for (int i
= 0; i
< strList
.getLength(); ++i
)
92 if ( !isAscii( strList
[i
] ) )
98 inline static void checkNullable() {}
100 //==========================================================================
101 //= OConfigurationRegistryKey
102 //==========================================================================
105 rtl::OUString
getNodeName(const com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
>& _xNode
)
107 com::sun::star::uno::Reference
< com::sun::star::container::XNamed
> xName( _xNode
, com::sun::star::uno::UNO_QUERY
);
109 return xName
->getName();
111 OSL_ENSURE( !_xNode
.is(), "Cannot get name of node");
112 return rtl::OUString();
114 //--------------------------------------------------------------------------
116 static bool splitPath(const rtl::OUString
& _sPath
, rtl::OUString
& _rsParentPath
, rtl::OUString
& _rsLocalName
);
117 //--------------------------------------------------------------------------
119 OConfigurationRegistryKey::OConfigurationRegistryKey
120 (const com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
>& _rxRootNode
121 ,sal_Bool _bWriteable
124 :m_bReadOnly(!_bWriteable
)
125 ,m_xNode(_rxRootNode
)
127 ,m_sLocalName() // this will be treated as root - maybe use hierarchical name (ß)
129 OSL_ENSURE(m_xNode
.is(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid config node param !");
132 //--------------------------------------------------------------------------
133 OConfigurationRegistryKey::OConfigurationRegistryKey
134 (const com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
>& _rxNode
135 ,sal_Bool _bWriteable
137 :m_bReadOnly(!_bWriteable
)
140 ,m_sLocalName( getNodeName(_rxNode
) ) // this will not be treated as root
142 OSL_ENSURE(m_xNode
.is(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid config node param !");
145 //--------------------------------------------------------------------------
146 OConfigurationRegistryKey::OConfigurationRegistryKey(
147 com::sun::star::uno::Any _rCurrentValue
,
148 const com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
>& _rxParentNode
,
149 const ::rtl::OUString
& _rLocalName
,
150 sal_Bool _bWriteable
)
151 :m_bReadOnly(!_bWriteable
)
153 ,m_xParentNode(_rxParentNode
)
154 ,m_sLocalName(_rLocalName
)
156 OSL_ENSURE(m_xParentNode
.is(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid parent node param !");
157 OSL_ENSURE(m_sLocalName
.getLength(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid relative name !");
158 OSL_ENSURE(m_xParentNode
->hasByName( m_sLocalName
), "OConfigurationRegistryKey::OConfigurationRegistryKey : key not found in parent node !" ); //
159 OSL_ENSURE(m_xParentNode
->getByName( m_sLocalName
) == _rCurrentValue
, "OConfigurationRegistryKey::OConfigurationRegistryKey : wrong value parameter !" ); //
161 _rCurrentValue
>>= m_xNode
; // we don't care if that fails
163 //--------------------------------------------------------------------------
165 com::sun::star::uno::Reference
<com::sun::star::beans::XPropertySetInfo
> OConfigurationRegistryKey::implGetParentPropertyInfo() throw(com::sun::star::uno::RuntimeException
)
167 if (!m_xParentNode
.is())
169 com::sun::star::uno::Reference
< com::sun::star::container::XChild
> xChild(m_xNode
, com::sun::star::uno::UNO_QUERY
);
171 m_xParentNode
= m_xParentNode
.query(xChild
->getParent());
174 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> xParentInfo
; // the result
176 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xParentProperties(m_xParentNode
, com::sun::star::uno::UNO_QUERY
);
177 if (xParentProperties
.is())
179 xParentInfo
= xParentProperties
->getPropertySetInfo();
180 if (xParentInfo
.is() && !xParentInfo
->hasPropertyByName(m_sLocalName
))
182 OSL_ENSURE(false, "OConfigurationRegistryKey: This key is unknown in the parent node's PropertySetInfo !");
183 xParentInfo
.clear(); // this key is unknow, so don't return the info
189 //--------------------------------------------------------------------------
192 sal_Bool
isNodeReadOnly(com::sun::star::uno::Reference
< com::sun::star::uno::XInterface
> const& _xNode
) throw(com::sun::star::uno::RuntimeException
)
194 OSL_ASSERT( _xNode
.is() );
196 com::sun::star::uno::Reference
< com::sun::star::beans::XProperty
> xProperty(_xNode
, com::sun::star::uno::UNO_QUERY
);
199 com::sun::star::beans::Property aProperty
= xProperty
->getAsProperty();
201 return (aProperty
.Attributes
& com::sun::star::beans::PropertyAttribute::READONLY
) != 0;
204 com::sun::star::uno::Reference
< com::sun::star::lang::XServiceInfo
> xServiceInfo( _xNode
, com::sun::star::uno::UNO_QUERY
);
205 if (xServiceInfo
.is())
207 // does it announce update capability ?
208 if (xServiceInfo
->supportsService(UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess")))
211 // else does it announce the expected service at all ?
212 else if (xServiceInfo
->supportsService(UNISTRING("com.sun.star.configuration.ConfigurationAccess")))
216 // no XProperty, no (meaningful) ServiceInfo - what can we do
220 //--------------------------------------------------------------------------
222 sal_Bool
OConfigurationRegistryKey::implIsReadOnly() throw (com::sun::star::uno::RuntimeException
)
224 sal_Bool bResult
= m_bReadOnly
;;
226 // do checks only if this was requested to be writable
232 // try to ask the node itself
233 else if (m_xNode
.is())
235 bResult
= m_bReadOnly
= isNodeReadOnly( m_xNode
);
238 // else use the parent
239 else if (m_xParentNode
.is())
241 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> xParentInfo
= implGetParentPropertyInfo();
243 if (xParentInfo
.is())
245 com::sun::star::beans::Property aProperty
= xParentInfo
->getPropertyByName(m_sLocalName
);
247 bResult
= m_bReadOnly
= ((aProperty
.Attributes
& com::sun::star::beans::PropertyAttribute::READONLY
) != 0);
251 // no property info about this key ? - check if the parent itself is writable
253 // NOTE: do not set m_bReadOnly here, as we haven't really found out about this object
254 bResult
= isNodeReadOnly( m_xParentNode
);
260 OSL_ENSURE(false, "implIsReadOnly called for invalid object");
261 bResult
= true; // no object is certainly not writable ;-)
266 //--------------------------------------------------------------------------
268 sal_Bool
OConfigurationRegistryKey::implEnsureNode() throw (com::sun::star::registry::InvalidRegistryException
,com::sun::star::uno::RuntimeException
)
272 OSL_ENSURE( m_xParentNode
.is(), "implEnsureNode called for invalid registry key");
273 if (m_xParentNode
.is())
277 com::sun::star::uno::Any aNode
= m_xParentNode
->getByName( m_sLocalName
);
279 if ( !(aNode
>>= m_xNode
) )
280 OSL_ENSURE( ! (aNode
.hasValue() && aNode
.getValueTypeClass() == com::sun::star::uno::TypeClass_INTERFACE
),
281 "OConfigurationRegistryKey: Node object does not implement expected interface");
283 catch (com::sun::star::container::NoSuchElementException
& e
)
285 m_xParentNode
.clear();
287 rtl::OUString sMessage
= UNISTRING("Invalid OConfigurationRegistryKey. The node \"");
288 sMessage
+= m_sLocalName
;
289 sMessage
+= UNISTRING("\" was not found in the parent. Parent error message: \n");
290 sMessage
+= e
.Message
;
292 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
298 //--------------------------------------------------------------------------
300 com::sun::star::uno::Type
OConfigurationRegistryKey::implGetUnoType() throw (com::sun::star::uno::RuntimeException
)
302 com::sun::star::uno::Type aType
;
305 aType
= getCppuType(&m_xNode
); // Its just an interface type
307 else if (m_xParentNode
.is())
310 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> xParentInfo
= implGetParentPropertyInfo();
311 if (xParentInfo
.is())
313 aType
= xParentInfo
->getPropertyByName( m_sLocalName
).Type
;
317 aType
= m_xParentNode
->getElementType();
322 OSL_ASSERT( aType
.getTypeClass() == com::sun::star::uno::TypeClass_VOID
);
323 OSL_ENSURE( false, "implGetUnoType called for invalid registry key");
327 //--------------------------------------------------------------------------
329 sal_Bool
OConfigurationRegistryKey::implEnsureValue() throw (com::sun::star::uno::RuntimeException
)
334 OSL_ENSURE( m_xParentNode
.is(), "implEnsureValue called for invalid registry key");
335 if (!m_xParentNode
.is())
338 switch (implGetUnoType().getTypeClass())
340 case com::sun::star::uno::TypeClass_INTERFACE
:
343 case com::sun::star::uno::TypeClass_BYTE
:
344 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
345 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
346 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
347 case com::sun::star::uno::TypeClass_FLOAT
:
348 OSL_ENSURE(false, "Unexpected (UNSIGNED INTERGRAL or FLOAT) type found for configuration node");
350 case com::sun::star::uno::TypeClass_STRING
:
351 case com::sun::star::uno::TypeClass_BOOLEAN
:
352 case com::sun::star::uno::TypeClass_SHORT
:
353 case com::sun::star::uno::TypeClass_LONG
:
354 case com::sun::star::uno::TypeClass_HYPER
:
355 case com::sun::star::uno::TypeClass_DOUBLE
:
356 case com::sun::star::uno::TypeClass_SEQUENCE
:
359 case com::sun::star::uno::TypeClass_ANY
:
362 case com::sun::star::uno::TypeClass_VOID
:
363 OSL_ENSURE(false, "OConfigurationRegistryKey: Key does not exist or has VOID type");
367 OSL_ENSURE(false, "OConfigurationRegistryKey: Key has unexpected UNO type (class)");
371 //--------------------------------------------------------------------------
373 sal_Bool
OConfigurationRegistryKey::implIsValid() throw ()
375 return m_xNode
.is() || (m_xParentNode
.is() && m_xParentNode
->hasByName( m_sLocalName
) );
377 //--------------------------------------------------------------------------
379 void OConfigurationRegistryKey::checkValid(KEY_ACCESS_TYPE _eIntentedAccess
) throw (com::sun::star::registry::InvalidRegistryException
,com::sun::star::uno::RuntimeException
)
382 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The registry is not bound to a configuration node anymore."), THISREF());
383 // "anymore", because at the moment the ctor was called it probably was bound ....
385 switch (_eIntentedAccess
)
387 case KAT_VALUE_WRITE
:
388 if (implIsReadOnly())
389 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node is not writeable."), THISREF());
391 // !!! NO !!! BREAK !!!
394 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node is not a value, but an internal container."), THISREF());
396 if (!m_xParentNode
.is())
397 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node is invalid. It has no parent."), THISREF());
399 if (!implEnsureValue())
400 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration does not have a legal value type."), THISREF());
404 if (!implEnsureNode())
405 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node does not have children, it is a value node."), THISREF());
413 //--------------------------------------------------------------------------
414 com::sun::star::uno::Any
OConfigurationRegistryKey::implCreateDefaultElement(com::sun::star::uno::Type
const& _aValueType
) throw (com::sun::star::uno::RuntimeException
)
416 com::sun::star::uno::Any aReturn
;
418 switch (_aValueType
.getTypeClass())
420 case com::sun::star::uno::TypeClass_STRING
:
421 aReturn
<<= rtl::OUString();
424 // we don't distinguish between the different integer types or boolean
425 // (the RegistryKeyType is not granular enough),
426 // but we can't handle them all the same way here
427 case com::sun::star::uno::TypeClass_BYTE
:
428 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
429 case com::sun::star::uno::TypeClass_SHORT
:
430 aReturn
<<= (sal_Int16
)0;
433 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
434 case com::sun::star::uno::TypeClass_LONG
:
435 aReturn
<<= (sal_Int32
)0;
438 case com::sun::star::uno::TypeClass_BOOLEAN
:
439 aReturn
<<= sal_Bool(false);
442 // we cannot really handle 64-bit ints in the registry (but here we can)
443 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
444 case com::sun::star::uno::TypeClass_HYPER
:
445 OSL_ENSURE(false, "Warning: cannot handle 64-bit values correctly in registry");
446 aReturn
<<= (sal_Int64
)0;
449 // we cannot really handle doubles in the registry (but here we can)
450 case com::sun::star::uno::TypeClass_FLOAT
:
451 case com::sun::star::uno::TypeClass_DOUBLE
:
452 OSL_ENSURE(false, "Warning: cannot handle DOUBLE correctly in registry");
453 aReturn
<<= (double)0;
456 // we really want to leave an Any as NULL - hopefully this is acceptable to the set
457 case com::sun::star::uno::TypeClass_ANY
:
460 case com::sun::star::uno::TypeClass_SEQUENCE
:
461 if (_aValueType
== getBinaryDataType())
462 aReturn
<<= com::sun::star::uno::Sequence
< sal_Int8
>();
466 com::sun::star::uno::Type aElementType
= getSequenceElementType(_aValueType
);
467 switch (aElementType
.getTypeClass())
469 case com::sun::star::uno::TypeClass_STRING
:
470 aReturn
<<= com::sun::star::uno::Sequence
< rtl::OUString
>();
473 case com::sun::star::uno::TypeClass_BYTE
:
474 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
475 case com::sun::star::uno::TypeClass_SHORT
:
476 aReturn
<<= com::sun::star::uno::Sequence
< sal_Int16
>();
479 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
480 case com::sun::star::uno::TypeClass_LONG
:
481 aReturn
<<= com::sun::star::uno::Sequence
< sal_Int32
>();
484 case com::sun::star::uno::TypeClass_BOOLEAN
:
485 aReturn
<<= com::sun::star::uno::Sequence
< sal_Bool
>();
488 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
489 case com::sun::star::uno::TypeClass_HYPER
:
490 aReturn
<<= com::sun::star::uno::Sequence
< sal_Int64
>();
493 case com::sun::star::uno::TypeClass_FLOAT
:
494 case com::sun::star::uno::TypeClass_DOUBLE
:
495 aReturn
<<= com::sun::star::uno::Sequence
< double >();
498 case com::sun::star::uno::TypeClass_SEQUENCE
:
499 OSL_ENSURE(false, "Warning: cannot handle Sequence< BINARY > correctly in registry");
500 if (aElementType
== getBinaryDataType())
502 OSL_ENSURE(false, "Warning: cannot handle Sequence< BINARY > correctly in registry");
503 aReturn
<<= com::sun::star::uno::Sequence
< com::sun::star::uno::Sequence
< sal_Int8
> >();
507 // else FALL THRU to default
509 OSL_ENSURE(false, "Unexpected sequence element type for configuration node - returning NULL");
516 case com::sun::star::uno::TypeClass_INTERFACE
:
517 OSL_ENSURE(false, "Invalid call to OConfigurationRegistryKey::implCreateDefaultElement. Inner nodes must be created by a factory");
521 OSL_ENSURE(false, "Unexpected value type for configuration node - returning NULL");
526 OSL_ENSURE( aReturn
.getValueType() == _aValueType
|| (_aValueType
.getTypeClass() == com::sun::star::uno::TypeClass_ANY
&& !aReturn
.hasValue()),
527 "Warning: Unexpected data type found in Registry - returning similar value or NULL");
531 //--------------------------------------------------------------------------
532 com::sun::star::uno::Any
OConfigurationRegistryKey::implGetDescendant(const rtl::OUString
& _rDescendantName
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
534 com::sun::star::uno::Any aElementReturn
;
540 // implEnsureNode should have been called before this method
541 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getDescendant : invalid call !");
543 // this method should not be called if the object does not represent a container node ...
544 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("invalid object."), THISREF());
549 // look for a local member first
550 aElementReturn
= m_xNode
->getByName(_rDescendantName
);
552 catch(com::sun::star::container::NoSuchElementException
&)
554 // is it a (possibly) hierarchical name ?
555 if ( _rDescendantName
.indexOf('/') <0 ) throw;
557 // Yes, so try deep access
558 com::sun::star::uno::Reference
< com::sun::star::container::XHierarchicalNameAccess
> xDeepAccess( m_xNode
, com::sun::star::uno::UNO_QUERY
);
559 if (!xDeepAccess
.is())
560 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Nested element access not supported by this node."), THISREF());
562 aElementReturn
= xDeepAccess
->getByHierarchicalName(_rDescendantName
);
565 catch(com::sun::star::container::NoSuchElementException
&)
566 { // not allowed to leave the method, wrap it
567 rtl::OUString
sMessage(UNISTRING("There is no element named "));
568 sMessage
+= _rDescendantName
;
569 sMessage
+= UNISTRING(".");
570 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
572 catch(com::sun::star::lang::WrappedTargetException
& wte
)
573 { // allowed to be thrown by XNameAccess::getByName, but not allowed to leave this method
574 rtl::OUString
sMessage(UNISTRING("The configuration node could not provide an element for "));
575 sMessage
+= _rDescendantName
;
576 sMessage
+= UNISTRING(". Original Error: ");
577 sMessage
+= wte
.Message
;
578 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
581 return aElementReturn
;
584 //--------------------------------------------------------------------------
585 void OConfigurationRegistryKey::implSetValue(const com::sun::star::uno::Any
& _rValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
587 checkValid(KAT_VALUE_WRITE
);
589 // one possible interface
590 com::sun::star::uno::Reference
< com::sun::star::container::XNameReplace
> xParentValueAccess(m_xParentNode
, com::sun::star::uno::UNO_QUERY
);
591 if (xParentValueAccess
.is())
595 xParentValueAccess
->replaceByName(m_sLocalName
, _rValue
);
597 catch(com::sun::star::lang::IllegalArgumentException
& iae
)
599 rtl::OUString sMessage
= UNISTRING("Unable to replace the old value. The configuration node threw an ");
600 sMessage
+= UNISTRING("IllegalArgumentException: ");
601 sMessage
+= iae
.Message
;
602 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
604 catch(com::sun::star::container::NoSuchElementException
& nse
)
606 OSL_ENSURE(false, "OConfigurationRegistryKey::writeValueNode : a NoSuchElementException should be impossible !");
608 rtl::OUString sMessage
= UNISTRING("Unable to replace the old value. The configuration node threw an ");
609 sMessage
+= UNISTRING("NoSuchElementException: ");
610 sMessage
+= nse
.Message
;
611 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
613 catch(com::sun::star::lang::WrappedTargetException
& wte
)
615 rtl::OUString sMessage
= UNISTRING("Unable to replace the old value. The configuration node threw an ");
616 sMessage
+= UNISTRING("WrappedTargetException: ");
617 sMessage
+= wte
.Message
;
618 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
623 // not found - try other interface
624 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySet
> xParentPropertySet(m_xParentNode
, com::sun::star::uno::UNO_QUERY
);
625 if (xParentPropertySet
.is())
629 xParentPropertySet
->setPropertyValue(m_sLocalName
, _rValue
);
631 catch(com::sun::star::lang::IllegalArgumentException
& iae
)
633 rtl::OUString sMessage
= UNISTRING("Unable to set a new value. The configuration node threw an ");
634 sMessage
+= UNISTRING("IllegalArgumentException: ");
635 sMessage
+= iae
.Message
;
636 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
638 catch(com::sun::star::beans::UnknownPropertyException
& upe
)
640 OSL_ENSURE(false, "OConfigurationRegistryKey::writeValueNode : a UnknownPropertyException should be impossible !");
642 rtl::OUString sMessage
= UNISTRING("Unable to set a new value. The configuration node threw an ");
643 sMessage
+= UNISTRING("UnknownPropertyException: ");
644 sMessage
+= upe
.Message
;
645 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
647 catch(com::sun::star::beans::PropertyVetoException
& pve
)
649 rtl::OUString sMessage
= UNISTRING("Unable to set a new value. The configuration node threw an ");
650 sMessage
+= UNISTRING("PropertyVetoException: ");
651 sMessage
+= pve
.Message
;
652 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
654 catch(com::sun::star::lang::WrappedTargetException
& wte
)
656 rtl::OUString sMessage
= UNISTRING("Unable to set a new value. The configuration node threw an ");
657 sMessage
+= UNISTRING("WrappedTargetException: ");
658 sMessage
+= wte
.Message
;
659 throw com::sun::star::registry::InvalidRegistryException(sMessage
, THISREF());
664 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("No interface found on parent node for writing to configuration value node."), THISREF());
667 //--------------------------------------------------------------------------
668 ::rtl::OUString SAL_CALL
OConfigurationRegistryKey::getKeyName() throw(com::sun::star::uno::RuntimeException
)
673 //--------------------------------------------------------------------------
674 sal_Bool SAL_CALL
OConfigurationRegistryKey::isReadOnly() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
676 OSL_ASSERT(UnoApiLock::isHeld());
677 checkValid(KAT_META
);
681 //--------------------------------------------------------------------------
682 sal_Bool SAL_CALL
OConfigurationRegistryKey::isValid() throw(com::sun::star::uno::RuntimeException
)
684 OSL_ASSERT(UnoApiLock::isHeld());
685 // TODO : perhaps if the registry we're a part of is closed ....
686 return implIsValid();
689 //--------------------------------------------------------------------------
690 com::sun::star::registry::RegistryKeyType SAL_CALL
OConfigurationRegistryKey::getKeyType( const ::rtl::OUString
& /*_rKeyName*/ ) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
692 OSL_ASSERT(UnoApiLock::isHeld());
694 // no further checks are made (for performance reasons) ...
695 // Maybe we should check only KAT_META for consistency ?
696 checkValid(KAT_CHILD
);
698 return com::sun::star::registry::RegistryKeyType_KEY
;
701 //--------------------------------------------------------------------------
702 com::sun::star::registry::RegistryValueType SAL_CALL
OConfigurationRegistryKey::getValueType() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
704 checkValid(KAT_META
);
706 const com::sun::star::uno::Type aUnoType
= implGetUnoType();
708 switch (aUnoType
.getTypeClass())
710 case com::sun::star::uno::TypeClass_INTERFACE
: // this is really a case of 'no value type'
711 return com::sun::star::registry::RegistryValueType_NOT_DEFINED
;
713 case com::sun::star::uno::TypeClass_ANY
: // this is really a case of 'all value types allowed'
714 return com::sun::star::registry::RegistryValueType_NOT_DEFINED
;
716 case com::sun::star::uno::TypeClass_STRING
:
717 return com::sun::star::registry::RegistryValueType_STRING
;
719 case com::sun::star::uno::TypeClass_BYTE
:
720 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
721 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
722 OSL_ENSURE(false, "Unexpected UNSIGNED type found for configuration node");
725 case com::sun::star::uno::TypeClass_BOOLEAN
:
726 case com::sun::star::uno::TypeClass_SHORT
:
727 case com::sun::star::uno::TypeClass_LONG
:
728 return com::sun::star::registry::RegistryValueType_LONG
;
730 case com::sun::star::uno::TypeClass_FLOAT
:
731 case com::sun::star::uno::TypeClass_DOUBLE
:
732 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : registry does not support floating point numbers !");
733 return com::sun::star::registry::RegistryValueType_LONG
;
735 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
736 case com::sun::star::uno::TypeClass_HYPER
:
737 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : registry does not support 64-bit integer numbers !");
738 return com::sun::star::registry::RegistryValueType_LONG
;
740 case com::sun::star::uno::TypeClass_SEQUENCE
:
741 if ( aUnoType
.equals( getBinaryDataType() ) )
742 return com::sun::star::registry::RegistryValueType_BINARY
;
746 com::sun::star::uno::Type aElementType
= getSequenceElementType(aUnoType
);
748 switch (aElementType
.getTypeClass())
750 case com::sun::star::uno::TypeClass_STRING
:
751 return com::sun::star::registry::RegistryValueType_STRINGLIST
;
753 case com::sun::star::uno::TypeClass_BYTE
:
754 OSL_ASSERT(false); // this is caught by the 'binary' case
756 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
757 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
758 OSL_ENSURE(false, "Unexpected UNSIGNED-List type found for configuration node");
761 case com::sun::star::uno::TypeClass_BOOLEAN
:
762 case com::sun::star::uno::TypeClass_SHORT
:
763 case com::sun::star::uno::TypeClass_LONG
:
764 return com::sun::star::registry::RegistryValueType_LONGLIST
;
766 case com::sun::star::uno::TypeClass_FLOAT
:
767 case com::sun::star::uno::TypeClass_DOUBLE
:
768 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : registry does not support floating point number lists !");
769 return com::sun::star::registry::RegistryValueType_LONGLIST
;
771 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
772 case com::sun::star::uno::TypeClass_HYPER
:
773 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : registry does not support 64-bit integer number lists !");
774 return com::sun::star::registry::RegistryValueType_LONGLIST
;
776 case com::sun::star::uno::TypeClass_ANY
:
777 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : Unexpected: Any as sequence element type !");
778 return com::sun::star::registry::RegistryValueType_NOT_DEFINED
;
781 if (aElementType
.equals(getBinaryDataType()))
782 OSL_ENSURE(sal_False
,"OConfigurationRegistryKey::getValueType : Registry cannot support LIST of BINARY");
784 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : unknown sequence element type !");
786 return com::sun::star::registry::RegistryValueType_NOT_DEFINED
;
791 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::getValueType : unknown entry type !");
792 return com::sun::star::registry::RegistryValueType_NOT_DEFINED
;
796 //--------------------------------------------------------------------------
798 com::sun::star::uno::Any
OConfigurationRegistryKey::implGetValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
800 checkValid(KAT_VALUE
);
802 return m_xParentNode
->getByName( m_sLocalName
);
805 //--------------------------------------------------------------------------
806 sal_Int32 SAL_CALL
OConfigurationRegistryKey::getLongValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
808 com::sun::star::uno::Any aValue
= implGetValue();
810 sal_Int32
nLongValue(0);
811 switch (aValue
.getValueTypeClass())
813 // integral types that are small enough are straightforward
814 case com::sun::star::uno::TypeClass_BYTE
: { sal_Int8 nNativeValue
= 0; aValue
>>= nNativeValue
; nLongValue
= nNativeValue
; } break;
815 case com::sun::star::uno::TypeClass_BOOLEAN
: { sal_Bool nNativeValue
= false; aValue
>>= nNativeValue
; nLongValue
= nNativeValue
; } break;
816 case com::sun::star::uno::TypeClass_SHORT
: { sal_Int16 nNativeValue
; aValue
>>= nNativeValue
; nLongValue
= nNativeValue
; } break;
817 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
: { sal_uInt16 nNativeValue
; aValue
>>= nNativeValue
; nLongValue
= nNativeValue
; } break;
818 case com::sun::star::uno::TypeClass_LONG
: { sal_Int32 nNativeValue
; aValue
>>= nNativeValue
; nLongValue
= nNativeValue
; } break;
820 // this is lossless, but not value-preserving - use cast to avoid warnings
821 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
823 sal_uInt32 nNativeValue
;
824 aValue
>>= nNativeValue
;
825 nLongValue
= sal_Int32(nNativeValue
);
829 // the following are larger than Long - check for loss and throw if applicable
830 case com::sun::star::uno::TypeClass_HYPER
:
832 sal_Int64 nNativeValue
;
833 aValue
>>= nNativeValue
;
834 nLongValue
= sal_Int32(nNativeValue
);
836 // check for data loss
837 if (sal_Int64(nLongValue
) != nNativeValue
)
838 throw com::sun::star::registry::InvalidValueException(UNISTRING("Unsigned Hyper value too large for long; Value cannot be retrieved using registry."), THISREF());
842 case com::sun::star::uno::TypeClass_UNSIGNED_HYPER
:
844 sal_uInt64 nNativeValue
;
845 aValue
>>= nNativeValue
;
846 nLongValue
= sal_Int32(nNativeValue
);
848 // check for data loss
849 if (sal_uInt64(sal_uInt32(nLongValue
)) != nNativeValue
)
850 throw com::sun::star::registry::InvalidValueException(UNISTRING("Unsigned Hyper value too large for long; Value cannot be retrieved using registry."), THISREF());
854 // for floating point types we need a limit for loss checking
855 case com::sun::star::uno::TypeClass_FLOAT
:
856 OSL_ENSURE(false, "Unexpected type FLOAT in configuration node");
859 float fNativeValue
= 0;
860 if (aValue
>>= fNativeValue
)
861 aValue
<<= double(fNativeValue
);
865 case com::sun::star::uno::TypeClass_DOUBLE
:
867 double fNativeValue
= 0;
868 aValue
>>= fNativeValue
;
870 // find a reasonable allowed imprecision
871 const double fEps
= (2.*fNativeValue
+ 5.) * std::numeric_limits
<double>::epsilon();
873 // should be rounding here
874 nLongValue
= sal_Int32(fNativeValue
);
876 // check for data loss
877 bool bRecheck
= false;
879 double diff
= fNativeValue
-double(nLongValue
);
882 // substitute for rounding here
886 diff
= fNativeValue
-double(nLongValue
);
890 else if ( diff
< -fEps
)
892 // substitute for rounding here
896 diff
= fNativeValue
-double(nLongValue
);
903 if (diff
> fEps
|| diff
< -fEps
)
904 throw com::sun::star::registry::InvalidValueException(UNISTRING("Double value cannot fit in Long; Value cannot be retrieved using registry."), THISREF());
909 case com::sun::star::uno::TypeClass_VOID
:
910 // allow NULL values, if we maybe advertise this node as long
911 if (this->getValueType() == com::sun::star::registry::RegistryValueType_LONG
)
913 // else FALL THRU to exception
916 throw com::sun::star::registry::InvalidValueException(UNISTRING("This node does not contain a long (or a compatible) value."), THISREF());
921 //--------------------------------------------------------------------------
922 void SAL_CALL
OConfigurationRegistryKey::setLongValue( sal_Int32 _nValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
924 implSetValue(com::sun::star::uno::makeAny(_nValue
));
927 //--------------------------------------------------------------------------
928 com::sun::star::uno::Sequence
< sal_Int32
> SAL_CALL
OConfigurationRegistryKey::getLongListValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
930 com::sun::star::uno::Any aValue
= implGetValue();
932 com::sun::star::uno::Sequence
< sal_Int32
> aReturn
;
933 if (!aValue
.hasValue())
934 checkNullable();// let NULL values pass
936 else if (!(aValue
>>= aReturn
))
938 // TODO : maybe it's a sequence of sal_Int8 or anything like that which we're able to convert ....
940 throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node does not contain a list of longs !"), THISREF());
946 //--------------------------------------------------------------------------
947 void SAL_CALL
OConfigurationRegistryKey::setLongListValue( const com::sun::star::uno::Sequence
< sal_Int32
>& _seqValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
949 implSetValue(com::sun::star::uno::makeAny(_seqValue
));
952 //--------------------------------------------------------------------------
953 rtl::OUString SAL_CALL
OConfigurationRegistryKey::getAsciiValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
955 rtl::OUString sReturn
= getStringValue();
957 if (!isAscii(sReturn
))
958 throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node value (a string) is not pure ASCII !"), THISREF());
963 //--------------------------------------------------------------------------
964 void SAL_CALL
OConfigurationRegistryKey::setAsciiValue( const ::rtl::OUString
& _rValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
966 OSL_ENSURE( isAscii(_rValue
), "The string passesd to OConfigurationRegistryKey::setAsciiValue is not pure ASCII");
968 setStringValue(_rValue
);
971 //--------------------------------------------------------------------------
972 com::sun::star::uno::Sequence
< rtl::OUString
> SAL_CALL
OConfigurationRegistryKey::getAsciiListValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
974 com::sun::star::uno::Sequence
<rtl::OUString
> aReturn
= getStringListValue();
976 if (!isAscii(aReturn
))
977 throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node value (a string list) is not pure ASCII !"), THISREF());
982 //--------------------------------------------------------------------------
983 void SAL_CALL
OConfigurationRegistryKey::setAsciiListValue( const com::sun::star::uno::Sequence
< ::rtl::OUString
>& _seqValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
985 OSL_ENSURE( isAscii(_seqValue
), "The string passesd to OConfigurationRegistryKey::setAsciiValue is not pure ASCII");
987 setStringListValue(_seqValue
);
990 //--------------------------------------------------------------------------
991 ::rtl::OUString SAL_CALL
OConfigurationRegistryKey::getStringValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
993 com::sun::star::uno::Any aValue
= implGetValue();
995 rtl::OUString sReturn
;
996 if (!aValue
.hasValue())
997 checkNullable();// let NULL values pass
999 else if (!(aValue
>>= sReturn
))
1000 throw com::sun::star::registry::InvalidValueException(UNISTRING("This node does not contain a string value."), THISREF());
1005 //--------------------------------------------------------------------------
1006 void SAL_CALL
OConfigurationRegistryKey::setStringValue( const ::rtl::OUString
& _rValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1008 implSetValue(com::sun::star::uno::makeAny(_rValue
));
1011 //--------------------------------------------------------------------------
1012 com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
OConfigurationRegistryKey::getStringListValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
1014 com::sun::star::uno::Any aValue
= implGetValue();
1016 com::sun::star::uno::Sequence
< rtl::OUString
> aReturn
;
1017 if (!aValue
.hasValue())
1018 checkNullable();// let NULL values pass
1020 else if (!(aValue
>>= aReturn
))
1021 throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node does not contain a list of strings !"), THISREF());
1026 //--------------------------------------------------------------------------
1027 void SAL_CALL
OConfigurationRegistryKey::setStringListValue( const com::sun::star::uno::Sequence
< ::rtl::OUString
>& _seqValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1029 implSetValue(com::sun::star::uno::makeAny(_seqValue
));
1032 //--------------------------------------------------------------------------
1033 com::sun::star::uno::Sequence
< sal_Int8
> SAL_CALL
OConfigurationRegistryKey::getBinaryValue() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::registry::InvalidValueException
, com::sun::star::uno::RuntimeException
)
1035 com::sun::star::uno::Any aValue
= implGetValue();
1037 com::sun::star::uno::Sequence
< sal_Int8
> aReturn
;
1038 if (!aValue
.hasValue())
1039 checkNullable();// let NULL values pass
1041 else if (!(aValue
>>= aReturn
))
1044 throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node does not contain a list of strings !"), THISREF());
1047 //--------------------------------------------------------------------------
1048 void SAL_CALL
OConfigurationRegistryKey::setBinaryValue( const com::sun::star::uno::Sequence
< sal_Int8
>& _rValue
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1050 implSetValue(com::sun::star::uno::makeAny(_rValue
));
1053 //--------------------------------------------------------------------------
1054 com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> OConfigurationRegistryKey::implGetKey( const ::rtl::OUString
& _rKeyName
)
1055 throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1057 com::sun::star::uno::Any aDescendant
= implGetDescendant(_rKeyName
);
1058 if (aDescendant
.getValueType().getTypeClass() == com::sun::star::uno::TypeClass_INTERFACE
)
1060 com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
> xNode
;
1061 ::cppu::extractInterface(xNode
, aDescendant
);
1063 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("invalid descendant node. No XNameAccess found."), THISREF());
1064 return new OConfigurationRegistryKey(xNode
, !m_bReadOnly
);
1068 #if OSL_DEBUG_LEVEL > 1
1069 switch (aDescendant
.getValueType().getTypeClass())
1071 case com::sun::star::uno::TypeClass_STRING
:
1072 case com::sun::star::uno::TypeClass_SHORT
:
1073 case com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
1074 case com::sun::star::uno::TypeClass_BYTE
:
1075 case com::sun::star::uno::TypeClass_LONG
:
1076 case com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
1077 case com::sun::star::uno::TypeClass_BOOLEAN
:
1078 case com::sun::star::uno::TypeClass_SEQUENCE
:
1080 case com::sun::star::uno::TypeClass_VOID
: // NULL value found
1083 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::openKey : unknown, invalid or unhandled descendant value type !");
1087 OSL_ASSERT(m_xNode
.is());
1089 com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
> xDescParent(m_xNode
); // the parent config node of the descandent
1090 rtl::OUString
sDescRelativeName( _rKeyName
); // local name of the descendant within xDescParent
1092 if (!m_xNode
->hasByName(_rKeyName
)) // it is a hierarchical Path -> more work
1094 rtl::OUString sParentLocation
;
1096 if ( !splitPath(_rKeyName
, sParentLocation
, sDescRelativeName
) )
1098 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Cannot split path for value. The internal registry structure seems to be corrupt."), THISREF());
1101 if (sParentLocation
.getLength())
1103 com::sun::star::uno::Any aDescParent
= implGetDescendant(sParentLocation
);
1104 ::cppu::extractInterface(xDescParent
, aDescParent
);
1105 if (!xDescParent
.is())
1106 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The internal registry structure seems to be corrupt."), THISREF());
1110 OSL_ENSURE(xDescParent
.is(), "No Parent Node found for value ?");
1111 OSL_ENSURE(xDescParent
->hasByName(sDescRelativeName
), "Parent Node does not contain found value ?");
1113 return new OConfigurationRegistryKey(aDescendant
, xDescParent
, sDescRelativeName
, !m_bReadOnly
);
1117 //--------------------------------------------------------------------------
1118 com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> SAL_CALL
OConfigurationRegistryKey::openKey( const ::rtl::OUString
& _rKeyName
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1120 checkValid(KAT_CHILD
);
1122 return implGetKey(_rKeyName
);
1124 //--------------------------------------------------------------------------
1125 bool OConfigurationRegistryKey::checkRelativeKeyName(rtl::OUString
& _rKeyName
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1127 // no empty names allowed
1128 if (!_rKeyName
.getLength())
1129 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
1131 bool bCleanPath
= true;
1133 // cut trailing slashes
1134 sal_Int32 nCleanEnd
= _rKeyName
.getLength();
1135 while (nCleanEnd
> 0 && _rKeyName
[nCleanEnd
- 1] == '/' )
1140 if (m_xNode
-> hasByName(_rKeyName
))
1147 com::sun::star::uno::Reference
< com::sun::star::util::XStringEscape
> xSE(m_xNode
, com::sun::star::uno::UNO_QUERY
);
1149 sal_Bool bPreferLocal
= xSE
.is();
1153 com::sun::star::uno::Reference
< com::sun::star::lang::XServiceInfo
> xSI(m_xNode
, com::sun::star::uno::UNO_QUERY
);
1154 if (xSI
.is() && xSI
->supportsService(rtl::OUString::createFromAscii("com.sun.star.configuration.SetAccess")))
1155 bPreferLocal
= true;
1160 com::sun::star::uno::Reference
< com::sun::star::container::XHierarchicalNameAccess
> xHA(m_xNode
, com::sun::star::uno::UNO_QUERY
);
1161 rtl::OUString sCleanName
= _rKeyName
.copy(0, nCleanEnd
);
1163 if (xHA
.is() && xHA
->hasByHierarchicalName(sCleanName
))
1164 bPreferLocal
= false;
1167 if (bPreferLocal
&& xSE
.is())
1169 _rKeyName
= xSE
->escapeString(_rKeyName
);
1171 bCleanPath
= !bPreferLocal
;
1177 // no absolute names ("/...") allowed
1178 if (_rKeyName
.getStr()[0] == '/')
1179 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid. It must be a relative, not an absolute name."), THISREF());
1182 // the original name consists of slashes only
1183 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
1186 _rKeyName
= _rKeyName
.copy(0, nCleanEnd
);
1191 //--------------------------------------------------------------------------
1192 com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> SAL_CALL
OConfigurationRegistryKey::createKey( const ::rtl::OUString
& _rKeyName
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1194 checkValid(KAT_CHILD
);
1197 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key is read only."), THISREF());
1199 OSL_ENSURE(m_xNode
.is(), "OConfigurationRegistryKey::createKey : somebody changed the checkValid(KAT_CHILD) behaviour !");
1201 rtl::OUString
sKeyName(_rKeyName
);
1202 if (checkRelativeKeyName(sKeyName
))
1204 rtl::OUString sParentName
, sLocalName
;
1206 if (!splitPath(sKeyName
,sParentName
, sLocalName
))
1207 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
1209 if (sParentName
.getLength()) // it's a nested key name
1211 // check if we have the key already
1212 com::sun::star::uno::Reference
< com::sun::star::container::XHierarchicalNameAccess
> xDeepAccess(m_xNode
, com::sun::star::uno::UNO_QUERY
);
1213 if (xDeepAccess
.is() && xDeepAccess
->hasByHierarchicalName(sKeyName
))
1215 // already there - just open it
1216 return implGetKey(sKeyName
);
1219 // deep access, but not found. delegate it to a registry key which is one level above the to-be-created one
1220 com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> xSetNode
= implGetKey(sParentName
);
1223 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::createKey : somebody changed the implGetKey behaviour !");
1224 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("An internal error occured."), THISREF());
1226 return xSetNode
->createKey(sLocalName
); // problem: request for a/['b/c'] might find a/b/c
1229 sKeyName
= sLocalName
;
1232 // The requested new key is one level below ourself. Can't delegate the creation.
1233 if (m_xNode
->hasByName(sKeyName
) )
1235 // already there - just open it
1236 return implGetKey(sKeyName
);
1239 com::sun::star::uno::Reference
< com::sun::star::container::XNameContainer
> xContainer(m_xNode
, com::sun::star::uno::UNO_QUERY
);
1240 if (!xContainer
.is())
1241 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The configuration node represented by this key is not a set node, you can't insert keys."), THISREF());
1243 com::sun::star::uno::Any aValueToInsert
;
1245 com::sun::star::uno::Reference
< com::sun::star::lang::XSingleServiceFactory
> xChildFactory(xContainer
, com::sun::star::uno::UNO_QUERY
);
1246 if (xChildFactory
.is())
1248 // In the configuration API, the creation of a new child is two-stage process : first you create a child which
1249 // is "floating", i.e. does not belong to the configuration tree, yet. After filling it with values, you insert
1250 // it into the container node which was used for the creation.
1251 // We can't map this behaviour with the registry API, so we have to combine both steps
1253 // create a new floating child for the container node
1256 com::sun::star::uno::Reference
< com::sun::star::uno::XInterface
> xFloatingChild
= xChildFactory
->createInstance();
1257 OSL_ENSURE( xFloatingChild
.is(), "The newly created element is NULL !");
1259 com::sun::star::uno::Reference
< com::sun::star::container::XNameAccess
> xInsertedChild(xFloatingChild
, com::sun::star::uno::UNO_QUERY
);
1260 OSL_ENSURE( xInsertedChild
.is(), "The newly created element does not provide the required interface");
1262 if (!xInsertedChild
.is())
1263 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("An internal error occured. The objects provided by the configuration API are invalid."), THISREF());
1265 aValueToInsert
<<= xInsertedChild
; // xFloatingChild;
1267 catch (com::sun::star::uno::RuntimeException
&)
1268 { // allowed to leave this method
1271 catch (com::sun::star::uno::Exception
& e
)
1272 { // not allowed to leave this method
1273 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Unable to create a new child for the configuration node. Original error message as provided by the configuration API : ") += e
.Message
,
1276 OSL_ENSURE(aValueToInsert
.hasValue(), "New Child node did not get into the Any ?");
1280 // If the elements of the set are simple values, we need to create a matching value
1281 com::sun::star::uno::Type aElementType
= xContainer
->getElementType();
1282 aValueToInsert
= implCreateDefaultElement(aElementType
);
1284 OSL_ENSURE(aValueToInsert
.hasValue() || aElementType
.getTypeClass() == com::sun::star::uno::TypeClass_ANY
, "Internal error: NULL value created for new value element ?");
1287 // and immediately insert it into the container
1290 xContainer
->insertByName(sKeyName
, aValueToInsert
);
1292 catch (com::sun::star::lang::IllegalArgumentException
& e
)
1294 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("illegal argument to InsertByName: ") += e
.Message
, THISREF());
1296 catch (com::sun::star::container::ElementExistException
& e
)
1298 OSL_ENSURE(false, "There was an element of the same name inserted just now");
1300 // try to return that one
1301 try { return implGetKey(sKeyName
); }
1302 catch (com::sun::star::uno::Exception
&) { OSL_ENSURE(false, "But the other element cannot be retrieved"); }
1305 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Inserting raised a NoSuchElementException for an unavailable element ! Original error message : ") += e
.Message
, THISREF());
1307 catch (com::sun::star::lang::WrappedTargetException
& e
)
1309 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Inserting raised a WrappedTargetException. Original error message : ") += e
.Message
, THISREF());
1312 return new OConfigurationRegistryKey(aValueToInsert
, m_xNode
, sKeyName
, !m_bReadOnly
);
1315 //--------------------------------------------------------------------------
1316 void SAL_CALL
OConfigurationRegistryKey::closeKey() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1318 OSL_ASSERT(UnoApiLock::isHeld());
1319 checkValid(KAT_META
);
1321 bool bRoot
= (m_sLocalName
.getLength() == 0);
1323 if (!bRoot
) // don't close, if this is the root key ..
1326 m_xParentNode
.clear();
1327 // m_sLocalName = rtl::OUString(); - local name is const ...
1331 //--------------------------------------------------------------------------
1332 void SAL_CALL
OConfigurationRegistryKey::deleteKey( const rtl::OUString
& _rKeyName
) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1334 checkValid(KAT_CHILD
);
1336 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key is read only."), THISREF());
1338 rtl::OUString
sKeyName(_rKeyName
);
1339 if (checkRelativeKeyName(sKeyName
))
1341 rtl::OUString sParentName
, sLocalName
;
1343 if (!splitPath(sKeyName
,sParentName
, sLocalName
))
1344 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
1346 if (sParentName
.getLength()) // it's a nested key name
1348 com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> xSetNode
= implGetKey(sParentName
);
1351 OSL_ENSURE(sal_False
, "OConfigurationRegistryKey::createKey : somebody changed the implGetKey behaviour !");
1352 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("An internal error occured."), THISREF());
1354 xSetNode
->deleteKey(sLocalName
);
1358 sKeyName
= sLocalName
;
1361 // The requested new key is one level below ourself. Can't delegate the creation.
1362 com::sun::star::uno::Reference
< com::sun::star::container::XNameContainer
> xContainer(m_xNode
, com::sun::star::uno::UNO_QUERY
);
1363 if (!xContainer
.is())
1364 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The configuration node represented by this key is not a set node, you can't remove keys."), THISREF());
1366 // and immediately remove it from the container
1369 xContainer
->removeByName(sKeyName
);
1371 catch (com::sun::star::container::NoSuchElementException
& e
)
1373 if (e
.Message
.getLength())
1374 throw com::sun::star::registry::InvalidRegistryException(e
.Message
, THISREF());
1376 throw com::sun::star::registry::InvalidRegistryException((UNISTRING("There is no element named ") += sKeyName
) += UNISTRING(" to remove."), THISREF());
1378 catch (com::sun::star::lang::WrappedTargetException
& e
)
1380 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Removing a node caused a WrappedTargetException. Original error message : ") += e
.Message
, THISREF());
1384 //--------------------------------------------------------------------------
1385 com::sun::star::uno::Sequence
< com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> > SAL_CALL
OConfigurationRegistryKey::openKeys() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1387 checkValid(KAT_CHILD
);
1389 com::sun::star::uno::Sequence
< ::rtl::OUString
> aNames(m_xNode
->getElementNames());
1391 sal_Int32
const nCount
= aNames
.getLength();
1393 com::sun::star::uno::Sequence
< com::sun::star::uno::Reference
< com::sun::star::registry::XRegistryKey
> > aReturn(nCount
);
1395 for (sal_Int32 i
=0; i
<nCount
; ++i
)
1396 aReturn
[i
] = implGetKey(aNames
[i
]);
1401 //--------------------------------------------------------------------------
1402 com::sun::star::uno::Sequence
< ::rtl::OUString
> SAL_CALL
OConfigurationRegistryKey::getKeyNames() throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1404 checkValid(KAT_CHILD
);
1405 return m_xNode
->getElementNames();
1408 //--------------------------------------------------------------------------
1409 sal_Bool SAL_CALL
OConfigurationRegistryKey::createLink( const ::rtl::OUString
& /*aLinkName*/, const ::rtl::OUString
& /*aLinkTarget*/ ) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1411 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
1414 //--------------------------------------------------------------------------
1415 void SAL_CALL
OConfigurationRegistryKey::deleteLink( const ::rtl::OUString
& /*rLinkName*/ ) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1417 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
1420 //--------------------------------------------------------------------------
1421 ::rtl::OUString SAL_CALL
OConfigurationRegistryKey::getLinkTarget( const ::rtl::OUString
& /*rLinkName*/ ) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1423 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
1426 //--------------------------------------------------------------------------
1427 ::rtl::OUString SAL_CALL
OConfigurationRegistryKey::getResolvedName( const ::rtl::OUString
& /*aKeyName*/ ) throw(com::sun::star::registry::InvalidRegistryException
, com::sun::star::uno::RuntimeException
)
1429 throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
1431 //--------------------------------------------------------------------------
1432 //..........................................................................
1433 } // namespace configmgr
1434 //..........................................................................
1436 #include "configpath.hxx"
1437 #include "configexcept.hxx"
1439 bool configmgr::splitPath(const rtl::OUString
& _sPath
, rtl::OUString
& _rsParentPath
, rtl::OUString
& _rsLocalName
)
1441 bool bResult
= false;
1444 bool bAbsolute
= configmgr::configuration::Path::isAbsolutePath(_sPath
);
1445 configmgr::configuration::Path::Rep aPath
;
1449 configmgr::configuration::AbsolutePath parsedPath
= configmgr::configuration::AbsolutePath::parse(_sPath
) ;
1451 aPath
= parsedPath
.rep() ;
1455 configmgr::configuration::RelativePath parsedPath
= configmgr::configuration::RelativePath::parse(_sPath
) ;
1457 aPath
= parsedPath
.rep() ;
1459 //configmgr::configuration::Path::Rep aPath = bAbsolute ? configmgr::configuration::AbsolutePath::parse(_sPath).rep() : configmgr::configuration::RelativePath::parse(_sPath).rep();
1461 OSL_ENSURE(!aPath
.isEmpty(), "Trying to split an empty or root path");
1462 std::vector
<configuration::Path::Component
>::const_reverse_iterator aFirst
= aPath
.begin(), aLast
= aPath
.end();
1464 if (aFirst
!= aLast
)
1468 _rsLocalName
= aLast
->getName();
1469 _rsParentPath
= configmgr::configuration::Path::Rep(aFirst
,aLast
).toString(bAbsolute
);
1473 // else go on to fail
1475 catch (configuration::Exception
&)
1480 //..........................................................................