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: apifactory.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"
34 #include "apifactory.hxx"
35 #include "objectregistry.hxx"
37 #include "apitreeaccess.hxx"
38 #include "apitreeimplobj.hxx"
40 #include <com/sun/star/uno/Reference.hxx>
41 #include <com/sun/star/lang/XUnoTunnel.hpp>
43 #include "noderef.hxx"
44 #include "anynoderef.hxx"
46 #include "configexcept.hxx"
47 #include "configset.hxx"
51 //-----------------------------------------------------------------------------
52 namespace css
= ::com::sun::star
;
53 namespace uno
= css::uno
;
54 namespace lang
= css::lang
;
55 //-----------------------------------------------------------------------------
58 //-----------------------------------------------------------------------------
59 ObjectRegistry::~ObjectRegistry()
61 OSL_ENSURE(m_aMap
.empty(),"WARNING: Configuration Object Map: Some Objects were not revoked correctly");
64 //-----------------------------------------------------------------------------
66 Factory::Factory(rtl::Reference
<ObjectRegistry
> pRegistry
)
67 : m_pRegistry(pRegistry
)
70 OSL_ENSURE(pRegistry
.is(), "ERROR: Factory requires a Object Registry");
72 //-----------------------------------------------------------------------------
77 //-----------------------------------------------------------------------------
79 NodeElement
* Factory::implFind(configuration::NodeID
const& aNode
)
81 return m_pRegistry
->findElement(aNode
);
83 //-----------------------------------------------------------------------------
85 void Factory::doRegisterElement(configuration::NodeID
const& aNode
, NodeElement
* pElement
)
87 m_pRegistry
->registerElement(aNode
,pElement
);
89 //-----------------------------------------------------------------------------
91 void Factory::doRevokeElement(configuration::NodeID
const& aNode
, NodeElement
* pElement
)
93 m_pRegistry
->revokeElement(aNode
,pElement
);
95 //-----------------------------------------------------------------------------
97 ApiTreeImpl
& Factory::getImplementation(NodeElement
& rElement
)
99 return rElement
.getApiTree();
101 //-----------------------------------------------------------------------------
104 rtl::Reference
<configuration::Template
> Factory::implGetSetElementTemplate(rtl::Reference
< configuration::Tree
> const& aTree
, configuration::NodeRef
const& aNode
)
106 rtl::Reference
<configuration::Template
> aRet
;
107 if (configuration::isSetNode(aTree
,aNode
))
109 aRet
= aTree
->extractElementInfo(aNode
);
111 else if (!configuration::isGroupNode(aTree
,aNode
))
113 OSL_ENSURE( !configuration::isStructuralNode(aTree
,aNode
), "ERROR: Configuration: unknown kind of object");
114 throw configuration::Exception("INTERNAL ERROR: Cannot create template - Unexpected node type");
118 //-----------------------------------------------------------------------------
120 uno::Reference
< uno::XInterface
> Factory::implToUno(NodeElement
* pElement
)
123 return uno::Reference
< uno::XInterface
>(pElement
->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE
);
125 return uno::Reference
< uno::XInterface
>();
127 //-----------------------------------------------------------------------------
129 void Factory::implHaveNewElement(configuration::NodeID aNodeID
, NodeElement
* pElement
)
131 OSL_ENSURE(pElement
,"WARNING: New API object could not be created");
135 doRegisterElement(aNodeID
,pElement
);
136 OSL_ENSURE(implFind(aNodeID
) == pElement
,"WARNING: New API object could not be registered with its factory");
139 //-----------------------------------------------------------------------------
141 uno::Reference
< uno::XInterface
> Factory::makeUnoElement(rtl::Reference
< configuration::Tree
> const& aTree
, configuration::NodeRef
const& aNode
)
143 return implToUno(makeElement(aTree
,aNode
));
145 //-----------------------------------------------------------------------------
146 NodeElement
* Factory::makeElement(rtl::Reference
< configuration::Tree
> const& aTree
, configuration::NodeRef
const& aNode
)
148 OSL_PRECOND( !configuration::isEmpty(aTree
.get()) == aNode
.isValid(), "ERROR: Configuration: Making element from tree requires valid node");
149 if (configuration::isEmpty(aTree
.get()))
152 OSL_PRECOND( aNode
.isValid() && aTree
->isValidNode(aNode
.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
153 OSL_PRECOND( configuration::isStructuralNode(aTree
,aNode
), "ERROR: Configuration: Cannot make object for value node");
155 configuration::NodeID
aNodeID(aTree
,aNode
);
156 NodeElement
* pRet
= findElement(aNodeID
);
159 rtl::Reference
<configuration::Template
> aTemplate
= implGetSetElementTemplate(aTree
,aNode
);
161 if (!aTree
->isRootNode(aNode
))
163 pRet
= doCreateGroupMember(aTree
,aNode
,aTemplate
.get());
167 rtl::Reference
< configuration::ElementTree
> aElementTree(dynamic_cast< configuration::ElementTree
* >(aTree
.get()));
168 if (aElementTree
.is())
170 pRet
= doCreateSetElement(aElementTree
,aTemplate
.get());
174 OSL_ENSURE(configuration::isEmpty(aTree
->getContextTree()),"INTERNAL ERROR: Found tree (not a set element) with a parent tree.");
175 pRet
= doCreateAccessRoot(aTree
,aTemplate
.get(), vos::ORef
< OOptions
>());
178 implHaveNewElement(aNodeID
,pRet
);
182 //-----------------------------------------------------------------------------
184 uno::Reference
< uno::XInterface
> Factory::findUnoElement(configuration::NodeID
const& aNodeID
)
186 return implToUno(findElement(aNodeID
));
188 //-----------------------------------------------------------------------------
189 NodeElement
* Factory::findElement(configuration::NodeID
const& aNodeID
)
191 NodeElement
* pReturn
= implFind(aNodeID
);
192 if (pReturn
) pReturn
->getUnoInstance()->acquire();
195 //-----------------------------------------------------------------------------
197 void Factory::revokeElement(configuration::NodeID
const& aNodeID
)
199 if (NodeElement
* pElement
= implFind(aNodeID
))
200 doRevokeElement(aNodeID
, pElement
);
202 //-----------------------------------------------------------------------------
204 TreeElement
* Factory::makeAccessRoot(rtl::Reference
< configuration::Tree
> const& aTree
, RequestOptions
const& _aOptions
)
206 OSL_PRECOND( !configuration::isEmpty(aTree
.get()) , "ERROR: Configuration: Making element from tree requires valid tree");
207 if (configuration::isEmpty(aTree
.get())) return 0;
209 OSL_ENSURE(configuration::isEmpty(aTree
->getContextTree()),"INTERNAL ERROR: Tree with parent tree should not be used for an access root");
210 OSL_ENSURE(dynamic_cast< configuration::ElementTree
* >(aTree
.get()) == 0, "INTERNAL ERROR: Element Tree should not be used for an access root");
212 configuration::NodeRef aRoot
= aTree
->getRootNode();
213 OSL_ENSURE(aRoot
.isValid(),"INTERNAL ERROR: Tree has no root node");
215 OSL_PRECOND( configuration::isStructuralNode(aTree
,aRoot
), "ERROR: Configuration: Cannot make object for value node");
217 configuration::NodeID
aNodeID(aTree
,aRoot
);
218 // must be a tree element if it is a tree root
219 TreeElement
* pRet
= static_cast<TreeElement
*>(findElement(aNodeID
));
222 rtl::Reference
<configuration::Template
> aTemplate
= implGetSetElementTemplate(aTree
,aRoot
);
223 vos::ORef
<OOptions
> xOptions
= new OOptions(_aOptions
);
224 pRet
= doCreateAccessRoot(aTree
,aTemplate
.get(), xOptions
);
225 implHaveNewElement (aNodeID
,pRet
);
229 //-----------------------------------------------------------------------------
231 uno::Reference
< uno::XInterface
> Factory::makeUnoSetElement(rtl::Reference
< configuration::ElementTree
> const& aElementTree
)
233 uno::Reference
< uno::XInterface
> aRet
= implToUno(makeSetElement(aElementTree
));
234 OSL_ENSURE( uno::Reference
<lang::XUnoTunnel
>::query(aRet
).is(),"ERROR: API set element has no UnoTunnel");
235 OSL_ENSURE( uno::Reference
<lang::XUnoTunnel
>::query(aRet
).is() &&
236 0 != uno::Reference
<lang::XUnoTunnel
>::query(aRet
)->getSomething(doGetElementTunnelID()),
237 "ERROR: API set element does not support the right tunnel ID");
241 //-----------------------------------------------------------------------------
243 SetElement
* Factory::makeSetElement(rtl::Reference
< configuration::ElementTree
> const& aElementTree
)
245 OSL_PRECOND( aElementTree
.is() , "ERROR: Configuration: Making element from tree requires valid tree");
246 if (!aElementTree
.is()) return 0;
248 rtl::Reference
< configuration::Tree
> aTree(aElementTree
.get());
249 OSL_ENSURE(!configuration::isEmpty(aTree
.get()),"INTERNAL ERROR: Element Tree has no Tree");
251 configuration::NodeRef aRoot
= aTree
->getRootNode();
252 OSL_ENSURE(aRoot
.isValid(),"INTERNAL ERROR: Tree has no root node");
254 OSL_ENSURE( configuration::isStructuralNode(aTree
,aRoot
), "ERROR: Configuration: Cannot make object for value node");
256 configuration::NodeID
aNodeID(aTree
,aRoot
);
257 // must be a set element if it wraps a ElementTree
258 SetElement
* pRet
= static_cast<SetElement
*>( findElement(aNodeID
) );
261 rtl::Reference
<configuration::Template
> aTemplate
= implGetSetElementTemplate(aTree
,aRoot
);
263 pRet
= doCreateSetElement(aElementTree
,aTemplate
.get());
265 implHaveNewElement(aNodeID
,pRet
);
269 //-----------------------------------------------------------------------------
271 SetElement
* Factory::findSetElement(rtl::Reference
< configuration::ElementTree
> const& aElement
)
273 OSL_PRECOND( aElement
.is() , "ERROR: Configuration: Making element from tree requires valid tree");
274 if (!aElement
.is()) return 0;
276 rtl::Reference
< configuration::Tree
> aTree(aElement
.get());
277 OSL_ENSURE(!isEmpty(aTree
.get()),"INTERNAL ERROR: Element Tree has no Tree");
279 configuration::NodeRef aRoot
= aTree
->getRootNode();
280 OSL_ENSURE(aRoot
.isValid(),"INTERNAL ERROR: Tree has no root node");
282 configuration::NodeID
aNodeID(aTree
,aRoot
);
283 // must be a set element if it wraps a ElementTree
284 SetElement
* pRet
= static_cast<SetElement
*>( findElement(aNodeID
) );
288 //-----------------------------------------------------------------------------
290 SetElement
* Factory::extractSetElement(uno::Any
const& aElement
)
292 SetElement
* pTunneledImpl
= 0;
294 uno::Reference
< lang::XUnoTunnel
> xElementTunnel
;
295 if ( aElement
.hasValue() && (aElement
>>= xElementTunnel
) )
297 OSL_ASSERT( xElementTunnel
.is() );
299 sal_Int64 nSomething
= xElementTunnel
->getSomething(doGetElementTunnelID());
302 void* pVoid
= reinterpret_cast<void*>(nSomething
);
303 pTunneledImpl
= static_cast<SetElement
*>(pVoid
);
306 return pTunneledImpl
;
308 //-----------------------------------------------------------------------------
310 bool Factory::tunnelSetElement(sal_Int64
& nSomething
, SetElement
& rElement
, uno::Sequence
< sal_Int8
> const& aTunnelID
)
312 if (aTunnelID
== doGetElementTunnelID())
314 void* pVoid
= &rElement
;
315 nSomething
= reinterpret_cast<sal_Int64
>(pVoid
);
323 //-----------------------------------------------------------------------------
325 ApiTreeImpl
const* Factory::findDescendantTreeImpl(configuration::NodeID
const& aNode
, ApiTreeImpl
const* pImpl
)
327 ApiTreeImpl
* pRet
= 0;
330 if ( NodeElement
* pElement
= pImpl
->getFactory().implFind( aNode
) )
331 pRet
= &pElement
->getApiTree();
336 //-----------------------------------------------------------------------------