update dev300-m58
[ooovba.git] / configmgr / source / api2 / elementimpl.cxx
blob1b6dffcbf20ad991c278eb4aa2b4d1d5a96479bb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: elementimpl.cxx,v $
10 * $Revision: 1.17.14.1 $
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"
34 #include "elementimpl.hxx"
35 #include "apitreeaccess.hxx"
36 #include "apinodeaccess.hxx"
37 #include "apifactory.hxx"
38 #include "noderef.hxx"
39 #include "nodechange.hxx"
40 #include "nodechangeinfo.hxx"
41 #include "translatechanges.hxx"
42 #include "apitypes.hxx"
43 #include "configset.hxx"
44 #include "confignotifier.hxx"
45 #include "confsvccomponent.hxx"
46 #include "committer.hxx"
47 #include <com/sun/star/lang/DisposedException.hpp>
48 #include <com/sun/star/container/XNameContainer.hpp>
49 #include <com/sun/star/configuration/XTemplateContainer.hpp>
50 #include <osl/diagnose.h>
52 namespace configmgr
54 namespace configapi
56 //-----------------------------------------------------------------------------------
57 namespace lang = css::lang;
58 namespace util = css::util;
60 //-----------------------------------------------------------------------------------
62 // Interface methods
63 //-----------------------------------------------------------------------------------
65 // XChild
66 //-----------------------------------------------------------------------------------
68 uno::Reference< uno::XInterface > implGetParent(NodeAccess& rNode, InnerElement&) throw(uno::RuntimeException)
70 uno::Reference<uno::XInterface> xRet;
72 try
74 GuardedNodeData<NodeAccess> impl( rNode ); // no provider lock needed - tree must be prebuilt already
76 rtl::Reference< configuration::Tree > aTree(impl.getTree());
77 configuration::NodeRef aParentNode = aTree->getParent(impl.getNode());
79 uno::Any aAny = configapi::makeInnerElement( rNode.getFactory(), aTree, aParentNode );
81 if (!(aAny >>= xRet)) // no parent available
83 OSL_ASSERT(!xRet.is()); // make sure we return NULL
84 OSL_ENSURE(!aAny.hasValue(), "configmgr: BasicElement::getParent: could not extract parent - node is not an object");
87 catch (configuration::Exception& ex)
89 ExceptionMapper e(ex);
90 e.setContext( rNode.getUnoInstance() );
91 e.unhandled();
94 return xRet;
97 //-----------------------------------------------------------------------------------
99 uno::Reference< uno::XInterface > implGetParent(NodeAccess& rNode, SetElement& /*rElement*/) throw(uno::RuntimeException)
101 uno::Reference<uno::XInterface> xRet;
105 // assume shared lock for connected trees
106 GuardedNodeData<NodeAccess> impl( rNode ); // no provider lock needed - tree must be prebuilt already
108 rtl::Reference< configuration::Tree > aTree(impl.getTree());
110 rtl::Reference< configuration::Tree > aParentTree( aTree->getContextTree() );
112 if (!configuration::isEmpty(aParentTree.get()))
114 configuration::NodeRef aParentNode( aTree->getContextNodeRef() );
116 // assume shared factory for connected trees
117 uno::Any aAny = configapi::makeInnerElement( rNode.getFactory(), aParentTree, aParentNode );
119 if (!(aAny >>= xRet)) // no parent available
121 // should occur only if the any is void
122 OSL_ENSURE(!aAny.hasValue(), "configmgr: BasicSetElement::getParent: could not extract parent - node is not an object");
123 OSL_ASSERT(!xRet.is()); // make sure we return NULL
126 else
128 OSL_ASSERT(!xRet.is()); // make sure we return NULL
131 catch (configuration::Exception& ex)
133 ExceptionMapper e(ex);
134 e.setContext( rNode.getUnoInstance() );
135 e.unhandled();
138 return xRet;
140 //-----------------------------------------------------------------------------------
142 // UNSUPPORTED method
143 void implSetParent(NodeAccess& rNode, InnerElement& /*rElement*/, const uno::Reference< uno::XInterface >& /*xParent*/ )
144 throw(lang::NoSupportException, uno::RuntimeException)
146 UnoApiLock aLock;
148 rNode.checkAlive(); // Does locking internally, checks for disposed nodes
150 // TODO(?): allow for xParent == getParent()
151 throw lang::NoSupportException(
152 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("configmgr: BasicElement::setParent: cannot move Entry")),
153 rNode.getUnoInstance() );
155 //-----------------------------------------------------------------------------------
157 // preliminary implementation
158 void implSetParent(NodeAccess& rNode, SetElement& rElement, const uno::Reference< uno::XInterface >& xParent )
159 throw(lang::NoSupportException, uno::RuntimeException)
161 UnoApiLock aLock;
163 //implSetParent(rNode,xParent);
164 // TODO: lock the whole transaction ???? - would need Uno Tunneling ?
165 uno::Reference< uno::XInterface > xGotParent( implGetParent(rNode,rElement) );
166 uno::Reference< css::container::XNameContainer > xOldParent( xGotParent, uno::UNO_QUERY );
167 uno::Reference< css::container::XNameContainer > xNewParent( xParent, uno::UNO_QUERY );
169 if (xGotParent.is() && !xOldParent.is())
171 throw lang::NoSupportException(
172 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: this is not element of a container")),
173 rNode.getUnoInstance() );
175 if (xParent.is() && !xNewParent.is())
177 throw lang::NoSupportException(
178 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: new parent is no container")),
179 rNode.getUnoInstance() );
182 uno::Reference< uno::XInterface > xThis(rNode.getUnoInstance());
183 OSL_ASSERT(xThis.is());
185 if (xOldParent != xNewParent)
187 rtl::OUString const sName( implGetName(rNode,rElement) );
189 if (xParent.is())
191 rtl::OUString const sTemplate( implGetTemplateName(rElement) );
193 if (sTemplate.getLength() == 0)
195 throw lang::NoSupportException(
196 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: object has no recognizable type")),
197 xThis );
200 uno::Reference< css::configuration::XTemplateContainer > xNewTemplate( xParent, uno::UNO_QUERY );
201 if (!xNewTemplate.is())
203 throw lang::NoSupportException(
204 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: new parent has no element template")),
205 xThis );
208 if ( sTemplate != xNewTemplate->getElementTemplateName())
210 throw lang::NoSupportException(
211 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: object has wrong type")),
212 xThis );
215 if ( xNewParent->hasByName( sName ) )
217 throw lang::NoSupportException(
218 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: an object of this name already exists in new parent")),
219 xThis );
222 // TODO: check for circularity (i.e. that This is not one of new parent's ancestors) !!
225 // now do it
227 try
229 if ( xOldParent.is()) xOldParent->removeByName(sName);
230 if ( xNewParent.is()) xNewParent->insertByName(sName, uno::makeAny(xThis));
232 catch (uno::Exception& e)
234 e.Message = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: changing parent failed: "))
235 += e.Message;
237 if (xOldParent.is())
238 try
240 xOldParent->insertByName(sName, uno::makeAny(xThis));
242 catch(uno::Exception& bad)
244 e.Message += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n\t ! Could not restore old parent: ")) += bad.Message;
247 throw uno::RuntimeException(e.Message,xThis);
252 //-----------------------------------------------------------------------------
255 // XNamed
256 //-----------------------------------------------------------------------------
257 rtl::OUString implGetName(NodeAccess& rNode, NodeElement& ) throw(uno::RuntimeException)
259 rtl::OUString sRet;
262 GuardedNodeData<NodeAccess> impl( rNode ); // maybe passive only ?
264 rtl::Reference< configuration::Tree > aTree(impl.getTree());
265 configuration::NodeRef aNode(impl.getNode());
267 sRet = aTree->getSimpleNodeName(aNode.getOffset());
269 catch (configuration::Exception& ex)
271 ExceptionMapper e(ex);
272 e.setContext( rNode.getUnoInstance() );
273 e.unhandled();
276 return sRet;
278 //-----------------------------------------------------------------------------
280 // UNSUPPORTED method
281 void implSetName(NodeAccess & rNode, NodeElement& /*rElement*/, const rtl::OUString& /*aName*/ ) throw(uno::RuntimeException)
283 UnoApiLock aLock;
285 rNode.checkAlive(); // Does locking internally, checks for disposed nodes
287 // TODO(?): allow for aName == getName()
288 throw uno::RuntimeException(
289 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("configmgr: BasicElement::setName: cannot rename Entry")),
290 rNode.getUnoInstance() );
292 //-----------------------------------------------------------------------------
294 // TODO: Implementations for elements to be added to a container node
295 void implSetName(NodeAccess& rNode, SetElement& rElement, const rtl::OUString& aName ) throw(uno::RuntimeException)
297 UnoApiLock aLock;
299 // TODO: Implement
300 NodeElement& rDelegate = rElement;
301 implSetName(rNode,rDelegate,aName); // delegate to unsupported version
303 //-----------------------------------------------------------------------------
305 // XComponent & XInterface
306 //-----------------------------------------------------------------------------
308 //-----------------------------------------------------------------------------
310 void implDispose( SetElement& rElement) throw(uno::RuntimeException)
312 UnoApiLock aLock;
314 if (!rElement.disposeTree(false))
316 throw uno::RuntimeException(
317 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Can't dispose an object that has an owner")),
318 rElement.getUnoInstance() );
321 //-----------------------------------------------------------------------------
323 void implDispose( RootElement& rElement) throw(uno::RuntimeException)
325 UnoApiLock aLock;
327 if (!rElement.disposeTree())
329 throw lang::DisposedException(
330 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Can't dispose an object that already was disposed")),
331 rElement.getUnoInstance() );
334 //-----------------------------------------------------------------------------
336 void implDisposeObject( NodeAccess& ,SetElement& rElement) throw(uno::RuntimeException)
338 UnoApiLock aLock;
339 // FIXME: should we hold a ref on the element over this ?
340 // call apitreeaccess.hxx (doGetUnoInterface) & hold a ref / unref ?
341 // [or!] - call getApiTree & ref/unref on that ?
342 // [or!] - hold the ref inside the dispose method itself ...
343 rElement.disposeTree(true);
345 //-----------------------------------------------------------------------------
347 void implDisposeObject( NodeAccess& , RootElement& rElement) throw(uno::RuntimeException)
349 UnoApiLock aLock;
351 rElement.disposeTree();
353 //-----------------------------------------------------------------------------
355 void implDisposeObject( NodeAccess& rNode, InnerElement& ) throw(uno::RuntimeException)
357 UnoApiLock aLock;
359 rNode.disposeNode();
361 //-----------------------------------------------------------------------------
364 // XTypeProvider
365 //-----------------------------------------------------------------------------
367 uno::Sequence<sal_Int8> implGetImplementationId(NodeAccess& rNode, NodeElement& rElement)
368 throw(uno::RuntimeException)
370 DisposeGuard aLock(rNode);
371 ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
373 OSL_ENSURE(pInfo, "Configuration: Object has no implementation (service) info - cannot get implementation id");
374 if (!pInfo)
375 throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Object has no implementation information - cannot get implementation id")),rElement.getUnoInstance() );
377 return ServiceComponentImpl::getStaticImplementationId(pInfo);
379 //-----------------------------------------------------------------------------
381 // XServiceInfo
382 //-----------------------------------------------------------------------------
384 rtl::OUString implGetImplementationName( NodeAccess& rNode, NodeElement& rElement ) throw(uno::RuntimeException)
386 DisposeGuard aLock(rNode);
387 ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
388 OSL_ENSURE(pInfo, "Configuration: Object has no service info");
390 return ServiceInfoHelper(pInfo).getImplementationName();
392 //-----------------------------------------------------------------------------
394 sal_Bool implSupportsService( NodeAccess& rNode, NodeElement& rElement, const rtl::OUString& ServiceName ) throw(uno::RuntimeException)
396 DisposeGuard aLock(rNode);
397 ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
398 OSL_ENSURE(pInfo, "Configuration: Object has no service info");
400 return ServiceInfoHelper(pInfo).supportsService(ServiceName);
402 //-----------------------------------------------------------------------------
404 uno::Sequence< rtl::OUString > implGetSupportedServiceNames( NodeAccess& rNode, NodeElement& rElement ) throw(uno::RuntimeException)
406 DisposeGuard aLock(rNode);
407 ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
408 OSL_ENSURE(pInfo, "Configuration: Object has no service info");
410 return ServiceInfoHelper(pInfo).getSupportedServiceNames();
412 //-----------------------------------------------------------------------------
414 // Root only ------------------------------------------------------------------
416 // XLocalizable
417 // TODO: Implement locale support
418 //-----------------------------------------------------------------------------
420 lang::Locale implGetLocale( RootElement& rElement ) throw(uno::RuntimeException)
422 GuardedRootElement aLocked(rElement);
424 OSL_ENSURE(false,"CONFIGURATION: Locale information is not yetsupported.");
425 return lang::Locale();
427 //-----------------------------------------------------------------------------
429 void implSetLocale( RootElement& rElement, const css::lang::Locale& /*eLocale*/ ) throw(uno::RuntimeException)
431 UnoApiLock aLock;
432 // TODO: Implement if possible
433 rElement.checkAlive();
435 OSL_ENSURE(false,"CONFIGURATION: Changing the set Locale is not supported.");
436 throw uno::RuntimeException(
437 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Changing the locale is currently not supported")),
438 rElement.getUnoInstance()
441 //-----------------------------------------------------------------------------
443 // XChangesBatch
444 //-----------------------------------------------------------------------------
446 void implCommitChanges( UpdateRootElement& rElement ) throw(css::lang::WrappedTargetException, uno::RuntimeException)
448 UnoApiLock aLock;
450 // quick check to avoid big locks for nothing (has its own locking)
451 if (!implHasPendingChanges(rElement)) return;
455 rElement.getCommitter().commit();
458 catch (configuration::Exception& ex)
460 ExceptionMapper e(ex);
461 e.setContext( rElement.getUnoInstance() );
462 e.unhandled();
465 // filter/wrap uno::Exceptions
466 catch (lang::WrappedTargetException& ) { throw; }
467 catch (uno::RuntimeException& ) { throw; }
468 catch (uno::Exception& ex)
470 uno::Reference<uno::XInterface> xContext( rElement.getUnoInstance() );
471 rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration: can't commit Changes: ") );
472 throw lang::WrappedTargetException( sMessage += ex.Message, xContext, uno::makeAny(ex));
475 //-----------------------------------------------------------------------------
477 sal_Bool implHasPendingChanges( RootElement& rElement ) throw(uno::RuntimeException)
481 GuardedRootElement aLocked(rElement);
482 return aLocked.get().getTree()->hasChanges();
484 catch (configuration::Exception& ex)
486 ExceptionMapper e(ex);
487 e.setContext( rElement.getUnoInstance() );
488 e.unhandled();
491 OSL_ENSURE(false,"Unreachable Code");
492 return false;
494 //-----------------------------------------------------------------------------
496 uno::Sequence< css::util::ElementChange > implGetPendingChanges( RootElement& rElement )
497 throw(uno::RuntimeException)
499 std::vector<css::util::ElementChange> aResult;
502 GuardedRootElement aLocked(rElement);
504 rtl::Reference< configuration::Tree > aTree( aLocked.get().getTree() );
506 configuration::NodeChangesInformation aInfos;
509 configuration::NodeChanges aChanges;
510 if (aTree->collectChanges(aChanges))
512 aChanges.getChangesInfos(aInfos);
516 Factory& rFactory = rElement.getFactory();
518 for(std::vector< configuration::NodeChangeInformation >::const_iterator it = aInfos.begin(), stop = aInfos.end();
519 it != stop;
520 ++it)
522 css::util::ElementChange aChange;
523 fillChange(aChange,*it,aTree,rFactory);
524 aResult.push_back(aChange);
527 catch (configuration::Exception& ex)
529 ExceptionMapper e(ex);
530 e.setContext( rElement.getUnoInstance() );
531 e.unhandled();
534 return makeSequence(aResult);
536 //-----------------------------------------------------------------------------
538 // Set only -------------------------------------------------------------------------
540 // XTemplateInstance
541 //-----------------------------------------------------------------------------------
543 rtl::OUString implGetTemplateName(SetElement& rElement)
544 throw(uno::RuntimeException)
548 GuardedTreeElement aLocked(rElement);
549 return rElement.getTemplateInfo()->getPathString();
551 catch (configuration::Exception& ex)
553 ExceptionMapper e(ex);
554 e.setContext( rElement.getUnoInstance() );
555 e.unhandled();
558 OSL_ENSURE(false,"Unreachable Code");
559 return rtl::OUString();
561 //-----------------------------------------------------------------------------------
563 // XUnoTunnel
564 //-----------------------------------------------------------------------------------
565 sal_Int64 implGetSomething(SetElement& rElement, const uno::Sequence< sal_Int8 >& aIdentifier )
566 throw(uno::RuntimeException)
568 sal_Int64 nSomething = 0;
571 GuardedTreeElement aLocked(rElement);
573 if (!rElement.getFactory().tunnelSetElement(nSomething, rElement, aIdentifier))
574 OSL_ASSERT(nSomething == 0);
576 catch (configuration::Exception& ex)
578 ExceptionMapper e(ex);
579 e.setContext( rElement.getUnoInstance() );
580 e.unhandled();
583 return nSomething;
585 //-----------------------------------------------------------------------------------
587 } // namespace configapi
589 } // namespace configmgr