137adc4f0SAndrew Rist /**************************************************************
237adc4f0SAndrew Rist  *
337adc4f0SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
437adc4f0SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
537adc4f0SAndrew Rist  * distributed with this work for additional information
637adc4f0SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
737adc4f0SAndrew Rist  * to you under the Apache License, Version 2.0 (the
837adc4f0SAndrew Rist  * "License"); you may not use this file except in compliance
937adc4f0SAndrew Rist  * with the License.  You may obtain a copy of the License at
1037adc4f0SAndrew Rist  *
1137adc4f0SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1237adc4f0SAndrew Rist  *
1337adc4f0SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1437adc4f0SAndrew Rist  * software distributed under the License is distributed on an
1537adc4f0SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1637adc4f0SAndrew Rist  * KIND, either express or implied.  See the License for the
1737adc4f0SAndrew Rist  * specific language governing permissions and limitations
1837adc4f0SAndrew Rist  * under the License.
1937adc4f0SAndrew Rist  *
2037adc4f0SAndrew Rist  *************************************************************/
2137adc4f0SAndrew Rist 
2237adc4f0SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "sal/config.h"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <algorithm>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "com/sun/star/connection/XConnection.hpp"
29cdf0e10cSrcweir #include "com/sun/star/uno/Exception.hpp"
30cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
31cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
32cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp"
33cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
34cdf0e10cSrcweir #include "cppuhelper/factory.hxx"
35cdf0e10cSrcweir #include "cppuhelper/implementationentry.hxx"
36cdf0e10cSrcweir #include "osl/diagnose.h"
37cdf0e10cSrcweir #include "rtl/ref.hxx"
38cdf0e10cSrcweir #include "sal/types.h"
39cdf0e10cSrcweir #include "uno/lbnames.h"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include "bridge.hxx"
42cdf0e10cSrcweir #include "bridgefactory.hxx"
43cdf0e10cSrcweir 
44cdf0e10cSrcweir namespace binaryurp {
45cdf0e10cSrcweir 
46cdf0e10cSrcweir namespace {
47cdf0e10cSrcweir 
48cdf0e10cSrcweir namespace css = com::sun::star;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir }
51cdf0e10cSrcweir 
static_create(css::uno::Reference<css::uno::XComponentContext> const & xContext)52cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > BridgeFactory::static_create(
53cdf0e10cSrcweir     css::uno::Reference< css::uno::XComponentContext > const & xContext)
54cdf0e10cSrcweir     SAL_THROW((css::uno::Exception))
55cdf0e10cSrcweir {
56cdf0e10cSrcweir     return static_cast< cppu::OWeakObject * >(new BridgeFactory(xContext));
57cdf0e10cSrcweir }
58cdf0e10cSrcweir 
static_getImplementationName()59cdf0e10cSrcweir rtl::OUString BridgeFactory::static_getImplementationName() {
60cdf0e10cSrcweir     return rtl::OUString(
61cdf0e10cSrcweir         RTL_CONSTASCII_USTRINGPARAM(
62cdf0e10cSrcweir             "com.sun.star.comp.bridge.BridgeFactory"));
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir css::uno::Sequence< rtl::OUString >
static_getSupportedServiceNames()66cdf0e10cSrcweir BridgeFactory::static_getSupportedServiceNames() {
67cdf0e10cSrcweir     rtl::OUString name(
68cdf0e10cSrcweir         RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory"));
69cdf0e10cSrcweir     return css::uno::Sequence< rtl::OUString >(&name, 1);
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
removeBridge(css::uno::Reference<css::bridge::XBridge> const & bridge)72cdf0e10cSrcweir void BridgeFactory::removeBridge(
73cdf0e10cSrcweir     css::uno::Reference< css::bridge::XBridge > const & bridge)
74cdf0e10cSrcweir {
75cdf0e10cSrcweir     OSL_ASSERT(bridge.is());
76cdf0e10cSrcweir     rtl::OUString n(bridge->getName());
77cdf0e10cSrcweir     osl::MutexGuard g(*this);
78*0848378bSHerbert Dürr     if ( n.isEmpty() ) {
79cdf0e10cSrcweir         BridgeList::iterator i(
80cdf0e10cSrcweir             std::find(unnamed_.begin(), unnamed_.end(), bridge));
81cdf0e10cSrcweir         if (i != unnamed_.end()) {
82cdf0e10cSrcweir             unnamed_.erase(i);
83cdf0e10cSrcweir         }
84cdf0e10cSrcweir     } else {
85cdf0e10cSrcweir         BridgeMap::iterator i(named_.find(n));
86cdf0e10cSrcweir         if (i != named_.end() && i->second == bridge) {
87cdf0e10cSrcweir             named_.erase(i);
88cdf0e10cSrcweir         }
89cdf0e10cSrcweir     }
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
BridgeFactory(css::uno::Reference<css::uno::XComponentContext> const & context)92cdf0e10cSrcweir BridgeFactory::BridgeFactory(
93cdf0e10cSrcweir     css::uno::Reference< css::uno::XComponentContext > const & context):
94cdf0e10cSrcweir     BridgeFactoryBase(*static_cast< osl::Mutex * >(this)), context_(context)
95cdf0e10cSrcweir {
96cdf0e10cSrcweir     OSL_ASSERT(context.is());
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
~BridgeFactory()99cdf0e10cSrcweir BridgeFactory::~BridgeFactory() {}
100cdf0e10cSrcweir 
getImplementationName()101cdf0e10cSrcweir rtl::OUString BridgeFactory::getImplementationName()
102cdf0e10cSrcweir     throw (css::uno::RuntimeException)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir     return static_getImplementationName();
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
supportsService(rtl::OUString const & ServiceName)107cdf0e10cSrcweir sal_Bool BridgeFactory::supportsService(rtl::OUString const & ServiceName)
108cdf0e10cSrcweir     throw (css::uno::RuntimeException)
109cdf0e10cSrcweir {
110cdf0e10cSrcweir     css::uno::Sequence< rtl::OUString > s(getSupportedServiceNames());
111cdf0e10cSrcweir     for (sal_Int32 i = 0; i != s.getLength(); ++i) {
112cdf0e10cSrcweir         if (ServiceName == s[i]) {
113cdf0e10cSrcweir             return true;
114cdf0e10cSrcweir         }
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir     return false;
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
getSupportedServiceNames()119cdf0e10cSrcweir css::uno::Sequence< rtl::OUString > BridgeFactory::getSupportedServiceNames()
120cdf0e10cSrcweir     throw (css::uno::RuntimeException)
121cdf0e10cSrcweir {
122cdf0e10cSrcweir     return static_getSupportedServiceNames();
123cdf0e10cSrcweir }
124cdf0e10cSrcweir 
createBridge(rtl::OUString const & sName,rtl::OUString const & sProtocol,css::uno::Reference<css::connection::XConnection> const & aConnection,css::uno::Reference<css::bridge::XInstanceProvider> const & anInstanceProvider)125cdf0e10cSrcweir css::uno::Reference< css::bridge::XBridge > BridgeFactory::createBridge(
126cdf0e10cSrcweir     rtl::OUString const & sName, rtl::OUString const & sProtocol,
127cdf0e10cSrcweir     css::uno::Reference< css::connection::XConnection > const & aConnection,
128cdf0e10cSrcweir     css::uno::Reference< css::bridge::XInstanceProvider > const &
129cdf0e10cSrcweir         anInstanceProvider)
130cdf0e10cSrcweir     throw (
131cdf0e10cSrcweir         css::bridge::BridgeExistsException, css::lang::IllegalArgumentException,
132cdf0e10cSrcweir         css::uno::RuntimeException)
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     rtl::Reference< Bridge > b;
135cdf0e10cSrcweir     {
136cdf0e10cSrcweir         osl::MutexGuard g(*this);
137cdf0e10cSrcweir         if (named_.find(sName) != named_.end()) {
138cdf0e10cSrcweir             throw css::bridge::BridgeExistsException(
139cdf0e10cSrcweir                 sName, static_cast< cppu::OWeakObject * >(this));
140cdf0e10cSrcweir         }
141cdf0e10cSrcweir         if (!(sProtocol.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("urp")) &&
142cdf0e10cSrcweir               aConnection.is()))
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             throw css::lang::IllegalArgumentException(
145cdf0e10cSrcweir                 rtl::OUString(
146cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM(
147cdf0e10cSrcweir                         "BridgeFactory::createBridge: sProtocol != urp ||"
148cdf0e10cSrcweir                         " aConnection == null")),
149cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >(this), -1);
150cdf0e10cSrcweir         }
151cdf0e10cSrcweir         b.set(new Bridge(this, sName, aConnection, anInstanceProvider));
152*0848378bSHerbert Dürr         if ( sName.isEmpty() ) {
153cdf0e10cSrcweir             unnamed_.push_back(
154cdf0e10cSrcweir                 css::uno::Reference< css::bridge::XBridge >(b.get()));
155cdf0e10cSrcweir         } else {
156cdf0e10cSrcweir             named_[sName] = b.get();
157cdf0e10cSrcweir         }
158cdf0e10cSrcweir     }
159cdf0e10cSrcweir     b->start();
160cdf0e10cSrcweir     return css::uno::Reference< css::bridge::XBridge >(b.get());
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
getBridge(rtl::OUString const & sName)163cdf0e10cSrcweir css::uno::Reference< css::bridge::XBridge > BridgeFactory::getBridge(
164cdf0e10cSrcweir     rtl::OUString const & sName) throw (css::uno::RuntimeException)
165cdf0e10cSrcweir {
166cdf0e10cSrcweir     osl::MutexGuard g(*this);
167cdf0e10cSrcweir     BridgeMap::iterator i(named_.find(sName));
168cdf0e10cSrcweir     return i == named_.end()
169cdf0e10cSrcweir         ? css::uno::Reference< css::bridge::XBridge >() : i->second;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir css::uno::Sequence< css::uno::Reference< css::bridge::XBridge > >
getExistingBridges()173cdf0e10cSrcweir BridgeFactory::getExistingBridges() throw (css::uno::RuntimeException) {
174cdf0e10cSrcweir     osl::MutexGuard g(*this);
175cdf0e10cSrcweir     if (unnamed_.size() > SAL_MAX_INT32) {
176cdf0e10cSrcweir         throw css::uno::RuntimeException(
177cdf0e10cSrcweir             rtl::OUString(
178cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
179cdf0e10cSrcweir                     "BridgeFactory::getExistingBridges: too many")),
180cdf0e10cSrcweir             static_cast< cppu::OWeakObject * >(this));
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir     sal_Int32 n = static_cast< sal_Int32 >(unnamed_.size());
183cdf0e10cSrcweir     if (named_.size() > static_cast< sal_uInt32 >(SAL_MAX_INT32 - n)) {
184cdf0e10cSrcweir         throw css::uno::RuntimeException(
185cdf0e10cSrcweir             rtl::OUString(
186cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
187cdf0e10cSrcweir                     "BridgeFactory::getExistingBridges: too many")),
188cdf0e10cSrcweir             static_cast< cppu::OWeakObject * >(this));
189cdf0e10cSrcweir     }
190cdf0e10cSrcweir     n = static_cast< sal_Int32 >(n + named_.size());
191cdf0e10cSrcweir     css::uno::Sequence< css::uno::Reference< css::bridge::XBridge > > s(n);
192cdf0e10cSrcweir     sal_Int32 i = 0;
193cdf0e10cSrcweir     for (BridgeList::iterator j(unnamed_.begin()); j != unnamed_.end(); ++j) {
194cdf0e10cSrcweir         s[i++] = *j;
195cdf0e10cSrcweir     }
196cdf0e10cSrcweir     for (BridgeMap::iterator j(named_.begin()); j != named_.end(); ++j) {
197cdf0e10cSrcweir         s[i++] = j->second;
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir     return s;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir namespace {
205cdf0e10cSrcweir 
206cdf0e10cSrcweir static cppu::ImplementationEntry const services[] = {
207cdf0e10cSrcweir     { &binaryurp::BridgeFactory::static_create,
208cdf0e10cSrcweir       &binaryurp::BridgeFactory::static_getImplementationName,
209cdf0e10cSrcweir       &binaryurp::BridgeFactory::static_getSupportedServiceNames,
210cdf0e10cSrcweir       &cppu::createSingleComponentFactory, 0, 0 },
211cdf0e10cSrcweir     { 0, 0, 0, 0, 0, 0 }
212cdf0e10cSrcweir };
213cdf0e10cSrcweir 
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
component_getFactory(char const * pImplName,void * pServiceManager,void * pRegistryKey)216cdf0e10cSrcweir extern "C" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
217cdf0e10cSrcweir     char const * pImplName, void * pServiceManager, void * pRegistryKey)
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     return cppu::component_getFactoryHelper(
220cdf0e10cSrcweir         pImplName, pServiceManager, pRegistryKey, services);
221cdf0e10cSrcweir }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL
component_getImplementationEnvironment(char const ** ppEnvTypeName,uno_Environment **)224cdf0e10cSrcweir component_getImplementationEnvironment(
225cdf0e10cSrcweir     char const ** ppEnvTypeName, uno_Environment **)
226cdf0e10cSrcweir {
227cdf0e10cSrcweir     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
228cdf0e10cSrcweir }
229