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