xref: /aoo41x/main/ucb/source/core/provprox.cxx (revision 2f86921c)
1*2f86921cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2f86921cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2f86921cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2f86921cSAndrew Rist  * distributed with this work for additional information
6*2f86921cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2f86921cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2f86921cSAndrew Rist  * "License"); you may not use this file except in compliance
9*2f86921cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2f86921cSAndrew Rist  *
11*2f86921cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2f86921cSAndrew Rist  *
13*2f86921cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2f86921cSAndrew Rist  * software distributed under the License is distributed on an
15*2f86921cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2f86921cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*2f86921cSAndrew Rist  * specific language governing permissions and limitations
18*2f86921cSAndrew Rist  * under the License.
19*2f86921cSAndrew Rist  *
20*2f86921cSAndrew Rist  *************************************************************/
21*2f86921cSAndrew Rist 
22*2f86921cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_ucb.hxx"
26cdf0e10cSrcweir #include <osl/diagnose.h>
27cdf0e10cSrcweir #include "provprox.hxx"
28cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir using namespace rtl;
31cdf0e10cSrcweir using namespace com::sun::star::lang;
32cdf0e10cSrcweir using namespace com::sun::star::ucb;
33cdf0e10cSrcweir using namespace com::sun::star::uno;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //=========================================================================
36cdf0e10cSrcweir //=========================================================================
37cdf0e10cSrcweir //
38cdf0e10cSrcweir // UcbContentProviderProxyFactory Implementation.
39cdf0e10cSrcweir //
40cdf0e10cSrcweir //=========================================================================
41cdf0e10cSrcweir //=========================================================================
42cdf0e10cSrcweir 
UcbContentProviderProxyFactory(const Reference<XMultiServiceFactory> & rxSMgr)43cdf0e10cSrcweir UcbContentProviderProxyFactory::UcbContentProviderProxyFactory(
44cdf0e10cSrcweir 						const Reference< XMultiServiceFactory >& rxSMgr )
45cdf0e10cSrcweir : m_xSMgr( rxSMgr )
46cdf0e10cSrcweir {
47cdf0e10cSrcweir }
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //=========================================================================
50cdf0e10cSrcweir // virtual
~UcbContentProviderProxyFactory()51cdf0e10cSrcweir UcbContentProviderProxyFactory::~UcbContentProviderProxyFactory()
52cdf0e10cSrcweir {
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
55cdf0e10cSrcweir //=========================================================================
56cdf0e10cSrcweir //
57cdf0e10cSrcweir // XInterface methods.
58cdf0e10cSrcweir //
59cdf0e10cSrcweir //=========================================================================
60cdf0e10cSrcweir 
61cdf0e10cSrcweir XINTERFACE_IMPL_3( UcbContentProviderProxyFactory,
62cdf0e10cSrcweir 				   XTypeProvider,
63cdf0e10cSrcweir 				   XServiceInfo,
64cdf0e10cSrcweir 				   XContentProviderFactory );
65cdf0e10cSrcweir 
66cdf0e10cSrcweir //=========================================================================
67cdf0e10cSrcweir //
68cdf0e10cSrcweir // XTypeProvider methods.
69cdf0e10cSrcweir //
70cdf0e10cSrcweir //=========================================================================
71cdf0e10cSrcweir 
72cdf0e10cSrcweir XTYPEPROVIDER_IMPL_3( UcbContentProviderProxyFactory,
73cdf0e10cSrcweir 	 		   		  XTypeProvider,
74cdf0e10cSrcweir 					  XServiceInfo,
75cdf0e10cSrcweir 	 		   		  XContentProviderFactory );
76cdf0e10cSrcweir 
77cdf0e10cSrcweir //=========================================================================
78cdf0e10cSrcweir //
79cdf0e10cSrcweir // XServiceInfo methods.
80cdf0e10cSrcweir //
81cdf0e10cSrcweir //=========================================================================
82cdf0e10cSrcweir 
83cdf0e10cSrcweir XSERVICEINFO_IMPL_1( UcbContentProviderProxyFactory,
84cdf0e10cSrcweir 					 OUString::createFromAscii(
85cdf0e10cSrcweir 		 				"com.sun.star.comp.ucb.UcbContentProviderProxyFactory" ),
86cdf0e10cSrcweir 					 OUString::createFromAscii(
87cdf0e10cSrcweir 		 				PROVIDER_FACTORY_SERVICE_NAME ) );
88cdf0e10cSrcweir 
89cdf0e10cSrcweir //=========================================================================
90cdf0e10cSrcweir //
91cdf0e10cSrcweir // Service factory implementation.
92cdf0e10cSrcweir //
93cdf0e10cSrcweir //=========================================================================
94cdf0e10cSrcweir 
95cdf0e10cSrcweir ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbContentProviderProxyFactory );
96cdf0e10cSrcweir 
97cdf0e10cSrcweir //=========================================================================
98cdf0e10cSrcweir //
99cdf0e10cSrcweir // XContentProviderFactory methods.
100cdf0e10cSrcweir //
101cdf0e10cSrcweir //=========================================================================
102cdf0e10cSrcweir 
103cdf0e10cSrcweir // virtual
104cdf0e10cSrcweir Reference< XContentProvider > SAL_CALL
createContentProvider(const OUString & Service)105cdf0e10cSrcweir UcbContentProviderProxyFactory::createContentProvider(
106cdf0e10cSrcweir 												const OUString& Service )
107cdf0e10cSrcweir 	throw( RuntimeException )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir 	return Reference< XContentProvider >(
110cdf0e10cSrcweir 						new UcbContentProviderProxy( m_xSMgr, Service ) );
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir //=========================================================================
114cdf0e10cSrcweir //=========================================================================
115cdf0e10cSrcweir //
116cdf0e10cSrcweir // UcbContentProviderProxy Implementation.
117cdf0e10cSrcweir //
118cdf0e10cSrcweir //=========================================================================
119cdf0e10cSrcweir //=========================================================================
120cdf0e10cSrcweir 
UcbContentProviderProxy(const Reference<XMultiServiceFactory> & rxSMgr,const OUString & Service)121cdf0e10cSrcweir UcbContentProviderProxy::UcbContentProviderProxy(
122cdf0e10cSrcweir 						const Reference< XMultiServiceFactory >& rxSMgr,
123cdf0e10cSrcweir 						const OUString& Service )
124cdf0e10cSrcweir : m_aService( Service ),
125cdf0e10cSrcweir   m_bReplace( sal_False ),
126cdf0e10cSrcweir   m_bRegister( sal_False ),
127cdf0e10cSrcweir   m_xSMgr( rxSMgr )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
131cdf0e10cSrcweir //=========================================================================
132cdf0e10cSrcweir // virtual
~UcbContentProviderProxy()133cdf0e10cSrcweir UcbContentProviderProxy::~UcbContentProviderProxy()
134cdf0e10cSrcweir {
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir //=========================================================================
138cdf0e10cSrcweir //
139cdf0e10cSrcweir // XInterface methods.
140cdf0e10cSrcweir //
141cdf0e10cSrcweir //=========================================================================
142cdf0e10cSrcweir 
143cdf0e10cSrcweir XINTERFACE_COMMON_IMPL( UcbContentProviderProxy );
144cdf0e10cSrcweir 
145cdf0e10cSrcweir //============================================================================
146cdf0e10cSrcweir // virtual
147cdf0e10cSrcweir Any SAL_CALL
queryInterface(const Type & rType)148cdf0e10cSrcweir UcbContentProviderProxy::queryInterface( const Type & rType )
149cdf0e10cSrcweir 	throw ( RuntimeException )
150cdf0e10cSrcweir {
151cdf0e10cSrcweir 	Any aRet = cppu::queryInterface( rType,
152cdf0e10cSrcweir 				static_cast< XTypeProvider * >( this ),
153cdf0e10cSrcweir 				static_cast< XServiceInfo * >( this ),
154cdf0e10cSrcweir 				static_cast< XContentProvider * >( this ),
155cdf0e10cSrcweir 				static_cast< XParameterizedContentProvider * >( this ),
156cdf0e10cSrcweir 				static_cast< XContentProviderSupplier * >( this ) );
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 	if ( !aRet.hasValue() )
159cdf0e10cSrcweir 		aRet = OWeakObject::queryInterface( rType );
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 	if ( !aRet.hasValue() )
162cdf0e10cSrcweir 	{
163cdf0e10cSrcweir 		// Get original provider an forward the call...
164cdf0e10cSrcweir 		osl::Guard< osl::Mutex > aGuard( m_aMutex );
165cdf0e10cSrcweir         Reference< XContentProvider > xProvider = getContentProvider();
166cdf0e10cSrcweir 		if ( xProvider.is() )
167cdf0e10cSrcweir 			aRet = xProvider->queryInterface( rType );
168cdf0e10cSrcweir 	}
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 	return aRet;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir //=========================================================================
174cdf0e10cSrcweir //
175cdf0e10cSrcweir // XTypeProvider methods.
176cdf0e10cSrcweir //
177cdf0e10cSrcweir //=========================================================================
178cdf0e10cSrcweir 
179cdf0e10cSrcweir XTYPEPROVIDER_COMMON_IMPL( UcbContentProviderProxy );
180cdf0e10cSrcweir 
181cdf0e10cSrcweir //=========================================================================
182cdf0e10cSrcweir 
getTypes()183cdf0e10cSrcweir Sequence< Type > SAL_CALL UcbContentProviderProxy::getTypes()                                                           \
184cdf0e10cSrcweir     throw( RuntimeException )
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     // Get original provider an forward the call...
187cdf0e10cSrcweir     osl::Guard< osl::Mutex > aGuard( m_aMutex );
188cdf0e10cSrcweir     Reference< XTypeProvider > xProvider( getContentProvider(), UNO_QUERY );
189cdf0e10cSrcweir     if ( xProvider.is() )
190cdf0e10cSrcweir     {
191cdf0e10cSrcweir         return xProvider->getTypes();
192cdf0e10cSrcweir     }
193cdf0e10cSrcweir     else
194cdf0e10cSrcweir     {
195cdf0e10cSrcweir         static cppu::OTypeCollection collection(
196cdf0e10cSrcweir             CPPU_TYPE_REF( XTypeProvider ),
197cdf0e10cSrcweir             CPPU_TYPE_REF( XServiceInfo ),
198cdf0e10cSrcweir             CPPU_TYPE_REF( XContentProvider ),
199cdf0e10cSrcweir             CPPU_TYPE_REF( XParameterizedContentProvider ),
200cdf0e10cSrcweir             CPPU_TYPE_REF( XContentProviderSupplier ) );
201cdf0e10cSrcweir         return collection.getTypes();
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir //=========================================================================
206cdf0e10cSrcweir //
207cdf0e10cSrcweir // XServiceInfo methods.
208cdf0e10cSrcweir //
209cdf0e10cSrcweir //=========================================================================
210cdf0e10cSrcweir 
211cdf0e10cSrcweir XSERVICEINFO_NOFACTORY_IMPL_1( UcbContentProviderProxy,
212cdf0e10cSrcweir 				 		   OUString::createFromAscii(
213cdf0e10cSrcweir 	 		   				"com.sun.star.comp.ucb.UcbContentProviderProxy" ),
214cdf0e10cSrcweir 				 		   OUString::createFromAscii(
215cdf0e10cSrcweir 	 						PROVIDER_PROXY_SERVICE_NAME ) );
216cdf0e10cSrcweir 
217cdf0e10cSrcweir //=========================================================================
218cdf0e10cSrcweir //
219cdf0e10cSrcweir // XContentProvider methods.
220cdf0e10cSrcweir //
221cdf0e10cSrcweir //=========================================================================
222cdf0e10cSrcweir 
223cdf0e10cSrcweir // virtual
queryContent(const Reference<XContentIdentifier> & Identifier)224cdf0e10cSrcweir Reference< XContent > SAL_CALL UcbContentProviderProxy::queryContent(
225cdf0e10cSrcweir 						const Reference< XContentIdentifier >& Identifier )
226cdf0e10cSrcweir 	throw( IllegalIdentifierException,
227cdf0e10cSrcweir 		   RuntimeException )
228cdf0e10cSrcweir {
229cdf0e10cSrcweir 	// Get original provider an forward the call...
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 	osl::Guard< osl::Mutex > aGuard( m_aMutex );
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	Reference< XContentProvider > xProvider = getContentProvider();
234cdf0e10cSrcweir 	if ( xProvider.is() )
235cdf0e10cSrcweir 		return xProvider->queryContent( Identifier );
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	return Reference< XContent >();
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir //=========================================================================
241cdf0e10cSrcweir // virtual
compareContentIds(const Reference<XContentIdentifier> & Id1,const Reference<XContentIdentifier> & Id2)242cdf0e10cSrcweir sal_Int32 SAL_CALL UcbContentProviderProxy::compareContentIds(
243cdf0e10cSrcweir 					   const Reference< XContentIdentifier >& Id1,
244cdf0e10cSrcweir 					   const Reference< XContentIdentifier >& Id2 )
245cdf0e10cSrcweir 	throw( RuntimeException )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir 	// Get original provider an forward the call...
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 	osl::Guard< osl::Mutex > aGuard( m_aMutex );
250cdf0e10cSrcweir 	Reference< XContentProvider > xProvider = getContentProvider();
251cdf0e10cSrcweir 	if ( xProvider.is() )
252cdf0e10cSrcweir 		return xProvider->compareContentIds( Id1, Id2 );
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     // OSL_ENSURE( sal_False,
255cdf0e10cSrcweir     // "UcbContentProviderProxy::compareContentIds - No provider!" );
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	// @@@ What else?
258cdf0e10cSrcweir 	return 0;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir 
261cdf0e10cSrcweir //=========================================================================
262cdf0e10cSrcweir //
263cdf0e10cSrcweir // XParameterizedContentProvider methods.
264cdf0e10cSrcweir //
265cdf0e10cSrcweir //=========================================================================
266cdf0e10cSrcweir 
267cdf0e10cSrcweir // virtual
268cdf0e10cSrcweir Reference< XContentProvider > SAL_CALL
registerInstance(const OUString & Template,const OUString & Arguments,sal_Bool ReplaceExisting)269cdf0e10cSrcweir UcbContentProviderProxy::registerInstance( const OUString& Template,
270cdf0e10cSrcweir 					  					   const OUString& Arguments,
271cdf0e10cSrcweir 					  					   sal_Bool ReplaceExisting )
272cdf0e10cSrcweir 	throw( IllegalArgumentException,
273cdf0e10cSrcweir 		   RuntimeException )
274cdf0e10cSrcweir {
275cdf0e10cSrcweir 	// Just remember that this method was called ( and the params ).
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 	osl::Guard< osl::Mutex > aGuard( m_aMutex );
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 	if ( !m_bRegister )
280cdf0e10cSrcweir 	{
281cdf0e10cSrcweir //		m_xTargetProvider = 0;
282cdf0e10cSrcweir 		m_aTemplate  = Template;
283cdf0e10cSrcweir 		m_aArguments = Arguments;
284cdf0e10cSrcweir 		m_bReplace   = ReplaceExisting;
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 		m_bRegister  = sal_True;
287cdf0e10cSrcweir 	}
288cdf0e10cSrcweir 	return this;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir //=========================================================================
292cdf0e10cSrcweir // virtual
293cdf0e10cSrcweir Reference< XContentProvider > SAL_CALL
deregisterInstance(const OUString & Template,const OUString & Arguments)294cdf0e10cSrcweir UcbContentProviderProxy::deregisterInstance( const OUString& Template,
295cdf0e10cSrcweir 											 const OUString& Arguments )
296cdf0e10cSrcweir 	throw( IllegalArgumentException,
297cdf0e10cSrcweir 		   RuntimeException )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir 	osl::Guard< osl::Mutex > aGuard( m_aMutex );
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	// registerInstance called at proxy and at original?
302cdf0e10cSrcweir 	if ( m_bRegister && m_xTargetProvider.is() )
303cdf0e10cSrcweir 	{
304cdf0e10cSrcweir 		m_bRegister       = sal_False;
305cdf0e10cSrcweir 		m_xTargetProvider = 0;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 		Reference< XParameterizedContentProvider >
308cdf0e10cSrcweir 								xParamProvider( m_xProvider, UNO_QUERY );
309cdf0e10cSrcweir 		if ( xParamProvider.is() )
310cdf0e10cSrcweir 		{
311cdf0e10cSrcweir 			try
312cdf0e10cSrcweir 			{
313cdf0e10cSrcweir                 xParamProvider->deregisterInstance( Template, Arguments );
314cdf0e10cSrcweir 			}
315cdf0e10cSrcweir 			catch ( IllegalIdentifierException const & )
316cdf0e10cSrcweir 			{
317cdf0e10cSrcweir 				OSL_ENSURE( sal_False,
318cdf0e10cSrcweir 					"UcbContentProviderProxy::deregisterInstance - "
319cdf0e10cSrcweir 					"Caught IllegalIdentifierException!" );
320cdf0e10cSrcweir 			}
321cdf0e10cSrcweir 		}
322cdf0e10cSrcweir 	}
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 	return this;
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir //=========================================================================
328cdf0e10cSrcweir //
329cdf0e10cSrcweir // XContentProviderSupplier methods.
330cdf0e10cSrcweir //
331cdf0e10cSrcweir //=========================================================================
332cdf0e10cSrcweir 
333cdf0e10cSrcweir // virtual
334cdf0e10cSrcweir Reference< XContentProvider > SAL_CALL
getContentProvider()335cdf0e10cSrcweir UcbContentProviderProxy::getContentProvider()
336cdf0e10cSrcweir 	throw( RuntimeException )
337cdf0e10cSrcweir {
338cdf0e10cSrcweir 	osl::Guard< osl::Mutex > aGuard( m_aMutex );
339cdf0e10cSrcweir 	if ( !m_xProvider.is() )
340cdf0e10cSrcweir 	{
341cdf0e10cSrcweir 		try
342cdf0e10cSrcweir 		{
343cdf0e10cSrcweir 			m_xProvider
344cdf0e10cSrcweir 				= Reference< XContentProvider >(
345cdf0e10cSrcweir 				  	m_xSMgr->createInstance( m_aService ), UNO_QUERY );
346cdf0e10cSrcweir             if(m_aArguments.compareToAscii("NoConfig") == 0)
347cdf0e10cSrcweir             {
348cdf0e10cSrcweir                 Reference<XInitialization> xInit(m_xProvider,UNO_QUERY);
349cdf0e10cSrcweir                 if(xInit.is()) {
350cdf0e10cSrcweir                     Sequence<Any> aArgs(1);
351cdf0e10cSrcweir                     aArgs[0] <<= m_aArguments;
352cdf0e10cSrcweir                     xInit->initialize(aArgs);
353cdf0e10cSrcweir                 }
354cdf0e10cSrcweir             }
355cdf0e10cSrcweir 		}
356cdf0e10cSrcweir 		catch ( RuntimeException const & )
357cdf0e10cSrcweir 		{
358cdf0e10cSrcweir 			throw;
359cdf0e10cSrcweir 		}
360cdf0e10cSrcweir 		catch ( Exception const & )
361cdf0e10cSrcweir 		{
362cdf0e10cSrcweir 		}
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 		// registerInstance called at proxy, but not yet at original?
365cdf0e10cSrcweir 		if ( m_xProvider.is() && m_bRegister )
366cdf0e10cSrcweir 		{
367cdf0e10cSrcweir 			Reference< XParameterizedContentProvider >
368cdf0e10cSrcweir 				xParamProvider( m_xProvider, UNO_QUERY );
369cdf0e10cSrcweir 			if ( xParamProvider.is() )
370cdf0e10cSrcweir 			{
371cdf0e10cSrcweir 				try
372cdf0e10cSrcweir 				{
373cdf0e10cSrcweir 					m_xTargetProvider
374cdf0e10cSrcweir 						= xParamProvider->registerInstance( m_aTemplate,
375cdf0e10cSrcweir 															m_aArguments,
376cdf0e10cSrcweir 															m_bReplace );
377cdf0e10cSrcweir 				}
378cdf0e10cSrcweir 				catch ( IllegalIdentifierException const & )
379cdf0e10cSrcweir 				{
380cdf0e10cSrcweir 					OSL_ENSURE( sal_False,
381cdf0e10cSrcweir 						"UcbContentProviderProxy::getContentProvider - "
382cdf0e10cSrcweir 						"Caught IllegalIdentifierException!" );
383cdf0e10cSrcweir 				}
384cdf0e10cSrcweir 
385cdf0e10cSrcweir 				OSL_ENSURE( m_xTargetProvider.is(),
386cdf0e10cSrcweir 					"UcbContentProviderProxy::getContentProvider - "
387cdf0e10cSrcweir 					"No provider!" );
388cdf0e10cSrcweir 			}
389cdf0e10cSrcweir 		}
390cdf0e10cSrcweir 		if ( !m_xTargetProvider.is() )
391cdf0e10cSrcweir 			m_xTargetProvider = m_xProvider;
392cdf0e10cSrcweir 	}
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	OSL_ENSURE( m_xProvider.is(),
395cdf0e10cSrcweir 				"UcbContentProviderProxy::getContentProvider - No provider!" );
396cdf0e10cSrcweir 	return m_xTargetProvider;
397cdf0e10cSrcweir }
398