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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26
27 #ifndef DBA_COREDATAACESS_COMPONENTDEFINITION_HXX
28 #include "ComponentDefinition.hxx"
29 #endif
30 #ifndef _DBASHARED_APITOOLS_HXX_
31 #include "apitools.hxx"
32 #endif
33 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
34 #include "dbastrings.hrc"
35 #endif
36 #include "module_dba.hxx"
37
38 #ifndef _TOOLS_DEBUG_HXX
39 #include <tools/debug.hxx>
40 #endif
41 #ifndef _COMPHELPER_SEQUENCE_HXX_
42 #include <comphelper/sequence.hxx>
43 #endif
44 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
45 #include <com/sun/star/lang/DisposedException.hpp>
46 #endif
47 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
48 #include <com/sun/star/beans/PropertyAttribute.hpp>
49 #endif
50 #ifndef _COMPHELPER_PROPERTY_HXX_
51 #include <comphelper/property.hxx>
52 #endif
53 #ifndef _DBACORE_DEFINITIONCOLUMN_HXX_
54 #include "definitioncolumn.hxx"
55 #endif
56 #include <cppuhelper/implbase1.hxx>
57 #include <comphelper/componentcontext.hxx>
58
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::sdbc;
61 using namespace ::com::sun::star::lang;
62
63 using namespace ::com::sun::star::beans;
64 using namespace ::com::sun::star::container;
65 using namespace ::osl;
66 using namespace ::comphelper;
67 using namespace ::cppu;
68
createRegistryInfo_OComponentDefinition()69 extern "C" void SAL_CALL createRegistryInfo_OComponentDefinition()
70 {
71 static ::dba::OAutoRegistration< ::dbaccess::OComponentDefinition > aAutoRegistration;
72 }
73
74 //........................................................................
75 namespace dbaccess
76 {
77 //........................................................................
78 /// helper class for column property change events which holds the OComponentDefinition weak
79 typedef ::cppu::WeakImplHelper1 < XPropertyChangeListener > TColumnPropertyListener_BASE;
80 class OColumnPropertyListener : public TColumnPropertyListener_BASE
81 {
82 OComponentDefinition* m_pComponent;
83
84 OColumnPropertyListener(const OColumnPropertyListener&);
85 void operator =(const OColumnPropertyListener&);
86 protected:
~OColumnPropertyListener()87 virtual ~OColumnPropertyListener(){}
88 public:
OColumnPropertyListener(OComponentDefinition * _pComponent)89 OColumnPropertyListener(OComponentDefinition* _pComponent) : m_pComponent(_pComponent){}
90 // XPropertyChangeListener
propertyChange(const PropertyChangeEvent &)91 virtual void SAL_CALL propertyChange( const PropertyChangeEvent& /*_rEvent*/ ) throw (RuntimeException)
92 {
93 if ( m_pComponent )
94 m_pComponent->notifyDataSourceModified();
95 }
96 // XEventListener
disposing(const EventObject &)97 virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException)
98 {
99 }
clear()100 void clear() { m_pComponent = NULL; }
101 };
DBG_NAME(OComponentDefinition_Impl)102 DBG_NAME(OComponentDefinition_Impl)
103 OComponentDefinition_Impl::OComponentDefinition_Impl()
104 {
105 DBG_CTOR(OComponentDefinition_Impl,NULL);
106 }
107 // -----------------------------------------------------------------------------
~OComponentDefinition_Impl()108 OComponentDefinition_Impl::~OComponentDefinition_Impl()
109 {
110 DBG_DTOR(OComponentDefinition_Impl,NULL);
111 }
112 //==========================================================================
113 //= OComponentDefinition
114 //==========================================================================
115 //--------------------------------------------------------------------------
DBG_NAME(OComponentDefinition)116 DBG_NAME(OComponentDefinition)
117 //--------------------------------------------------------------------------
118 void OComponentDefinition::registerProperties()
119 {
120 m_xColumnPropertyListener = ::comphelper::ImplementationReference<OColumnPropertyListener,XPropertyChangeListener>(new OColumnPropertyListener(this));
121 OComponentDefinition_Impl& rDefinition( getDefinition() );
122 ODataSettings::registerPropertiesFor( &rDefinition );
123
124 registerProperty(PROPERTY_NAME, PROPERTY_ID_NAME, PropertyAttribute::BOUND | PropertyAttribute::READONLY|PropertyAttribute::CONSTRAINED,
125 &rDefinition.m_aProps.aTitle, ::getCppuType(&rDefinition.m_aProps.aTitle));
126
127 if ( m_bTable )
128 {
129 registerProperty(PROPERTY_SCHEMANAME, PROPERTY_ID_SCHEMANAME, PropertyAttribute::BOUND,
130 &rDefinition.m_sSchemaName, ::getCppuType(&rDefinition.m_sSchemaName));
131
132 registerProperty(PROPERTY_CATALOGNAME, PROPERTY_ID_CATALOGNAME, PropertyAttribute::BOUND,
133 &rDefinition.m_sCatalogName, ::getCppuType(&rDefinition.m_sCatalogName));
134 }
135 }
136
137 //--------------------------------------------------------------------------
OComponentDefinition(const Reference<XMultiServiceFactory> & _xORB,const Reference<XInterface> & _xParentContainer,const TContentPtr & _pImpl,sal_Bool _bTable)138 OComponentDefinition::OComponentDefinition(const Reference< XMultiServiceFactory >& _xORB
139 ,const Reference< XInterface >& _xParentContainer
140 ,const TContentPtr& _pImpl
141 ,sal_Bool _bTable)
142 :OContentHelper(_xORB,_xParentContainer,_pImpl)
143 ,ODataSettings(OContentHelper::rBHelper,!_bTable)
144 ,m_bTable(_bTable)
145 {
146 DBG_CTOR(OComponentDefinition, NULL);
147 registerProperties();
148 }
149 //--------------------------------------------------------------------------
~OComponentDefinition()150 OComponentDefinition::~OComponentDefinition()
151 {
152 DBG_DTOR(OComponentDefinition, NULL);
153 }
154
155 //--------------------------------------------------------------------------
OComponentDefinition(const Reference<XInterface> & _rxContainer,const::rtl::OUString & _rElementName,const Reference<XMultiServiceFactory> & _xORB,const TContentPtr & _pImpl,sal_Bool _bTable)156 OComponentDefinition::OComponentDefinition( const Reference< XInterface >& _rxContainer
157 ,const ::rtl::OUString& _rElementName
158 ,const Reference< XMultiServiceFactory >& _xORB
159 ,const TContentPtr& _pImpl
160 ,sal_Bool _bTable)
161 :OContentHelper(_xORB,_rxContainer,_pImpl)
162 ,ODataSettings(OContentHelper::rBHelper,!_bTable)
163 ,m_bTable(_bTable)
164 {
165 DBG_CTOR(OComponentDefinition, NULL);
166 registerProperties();
167
168 m_pImpl->m_aProps.aTitle = _rElementName;
169 DBG_ASSERT(m_pImpl->m_aProps.aTitle.getLength() != 0, "OComponentDefinition::OComponentDefinition : invalid name !");
170 }
171
172 //--------------------------------------------------------------------------
173 IMPLEMENT_IMPLEMENTATION_ID(OComponentDefinition);
174 IMPLEMENT_GETTYPES3(OComponentDefinition,ODataSettings,OContentHelper,OComponentDefinition_BASE);
IMPLEMENT_FORWARD_XINTERFACE3(OComponentDefinition,OContentHelper,ODataSettings,OComponentDefinition_BASE)175 IMPLEMENT_FORWARD_XINTERFACE3( OComponentDefinition,OContentHelper,ODataSettings,OComponentDefinition_BASE)
176 //--------------------------------------------------------------------------
177 ::rtl::OUString OComponentDefinition::getImplementationName_static( ) throw(RuntimeException)
178 {
179 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.dba.OComponentDefinition"));
180 }
181
182 //--------------------------------------------------------------------------
getImplementationName()183 ::rtl::OUString SAL_CALL OComponentDefinition::getImplementationName( ) throw(RuntimeException)
184 {
185 return getImplementationName_static();
186 }
187
188 //--------------------------------------------------------------------------
getSupportedServiceNames_static()189 Sequence< ::rtl::OUString > OComponentDefinition::getSupportedServiceNames_static( ) throw(RuntimeException)
190 {
191 Sequence< ::rtl::OUString > aServices(2);
192 aServices.getArray()[0] = SERVICE_SDB_TABLEDEFINITION;
193 aServices.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.Content"));
194
195 return aServices;
196 }
197
198 //--------------------------------------------------------------------------
getSupportedServiceNames()199 Sequence< ::rtl::OUString > SAL_CALL OComponentDefinition::getSupportedServiceNames( ) throw(RuntimeException)
200 {
201 return getSupportedServiceNames_static();
202 }
203 //------------------------------------------------------------------------------
Create(const Reference<XComponentContext> & _rxContext)204 Reference< XInterface > OComponentDefinition::Create( const Reference< XComponentContext >& _rxContext )
205 {
206 ::comphelper::ComponentContext aContext( _rxContext );
207 return *(new OComponentDefinition( aContext.getLegacyServiceFactory(), NULL, TContentPtr( new OComponentDefinition_Impl ) ) );
208 }
209 // -----------------------------------------------------------------------------
disposing()210 void SAL_CALL OComponentDefinition::disposing()
211 {
212 OContentHelper::disposing();
213 if ( m_pColumns.get() )
214 m_pColumns->disposing();
215 m_xColumnPropertyListener->clear();
216 m_xColumnPropertyListener.dispose();
217 }
218 // -----------------------------------------------------------------------------
getInfoHelper()219 IPropertyArrayHelper& OComponentDefinition::getInfoHelper()
220 {
221 return *getArrayHelper();
222 }
223 //--------------------------------------------------------------------------
createArrayHelper() const224 IPropertyArrayHelper* OComponentDefinition::createArrayHelper( ) const
225 {
226 Sequence< Property > aProps;
227 describeProperties(aProps);
228 return new OPropertyArrayHelper(aProps);
229 }
230 //--------------------------------------------------------------------------
getPropertySetInfo()231 Reference< XPropertySetInfo > SAL_CALL OComponentDefinition::getPropertySetInfo( ) throw(RuntimeException)
232 {
233 Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) );
234 return xInfo;
235 }
236
237 // -----------------------------------------------------------------------------
determineContentType() const238 ::rtl::OUString OComponentDefinition::determineContentType() const
239 {
240 return m_bTable
241 ? ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseTable" ) )
242 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.org.openoffice.DatabaseCommandDefinition" ) );
243 }
244
245 // -----------------------------------------------------------------------------
getColumns()246 Reference< XNameAccess> OComponentDefinition::getColumns() throw (RuntimeException)
247 {
248 ::osl::MutexGuard aGuard(m_aMutex);
249 ::connectivity::checkDisposed(OContentHelper::rBHelper.bDisposed);
250
251 if ( !m_pColumns.get() )
252 {
253 ::std::vector< ::rtl::OUString> aNames;
254
255 const OComponentDefinition_Impl& rDefinition( getDefinition() );
256 aNames.reserve( rDefinition.size() );
257
258 OComponentDefinition_Impl::const_iterator aIter = rDefinition.begin();
259 OComponentDefinition_Impl::const_iterator aEnd = rDefinition.end();
260 for ( ; aIter != aEnd; ++aIter )
261 aNames.push_back( aIter->first );
262
263 m_pColumns.reset( new OColumns( *this, m_aMutex, sal_True, aNames, this, NULL, sal_True, sal_False, sal_False ) );
264 m_pColumns->setParent( *this );
265 }
266 return m_pColumns.get();
267 }
268 // -----------------------------------------------------------------------------
createColumn(const::rtl::OUString & _rName) const269 OColumn* OComponentDefinition::createColumn(const ::rtl::OUString& _rName) const
270 {
271 const OComponentDefinition_Impl& rDefinition( getDefinition() );
272 OComponentDefinition_Impl::const_iterator aFind = rDefinition.find( _rName );
273 if ( aFind != rDefinition.end() )
274 {
275 aFind->second->addPropertyChangeListener(::rtl::OUString(),m_xColumnPropertyListener.getRef());
276 return new OTableColumnWrapper( aFind->second, aFind->second, true );
277 }
278 OSL_ENSURE( false, "OComponentDefinition::createColumn: is this a valid case?" );
279 // This here is the last place creating a OTableColumn, and somehow /me thinks it is not needed ...
280 return new OTableColumn( _rName );
281 }
282 // -----------------------------------------------------------------------------
createColumnDescriptor()283 Reference< XPropertySet > OComponentDefinition::createColumnDescriptor()
284 {
285 return new OTableColumnDescriptor( true );
286 }
287 // -----------------------------------------------------------------------------
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any & rValue)288 void OComponentDefinition::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
289 {
290 ODataSettings::setFastPropertyValue_NoBroadcast(nHandle,rValue);
291 notifyDataSourceModified();
292 }
293 // -----------------------------------------------------------------------------
columnDropped(const::rtl::OUString & _sName)294 void OComponentDefinition::columnDropped(const ::rtl::OUString& _sName)
295 {
296 getDefinition().erase( _sName );
297 notifyDataSourceModified();
298 }
299 // -----------------------------------------------------------------------------
columnAppended(const Reference<XPropertySet> & _rxSourceDescriptor)300 void OComponentDefinition::columnAppended( const Reference< XPropertySet >& _rxSourceDescriptor )
301 {
302 ::rtl::OUString sName;
303 _rxSourceDescriptor->getPropertyValue( PROPERTY_NAME ) >>= sName;
304
305 Reference<XPropertySet> xColDesc = new OTableColumnDescriptor( true );
306 ::comphelper::copyProperties( _rxSourceDescriptor, xColDesc );
307 getDefinition().insert( sName, xColDesc );
308
309 // formerly, here was a setParent at the xColDesc. The parent used was an adapter (ChildHelper_Impl)
310 // which held another XChild weak, and forwarded all getParent requests to this other XChild.
311 // m_pColumns was used for this. This was nonsense, since m_pColumns dies when our instance dies,
312 // but xColDesc will live longer than this. So effectively, the setParent call was pretty useless.
313 //
314 // The intention for this parenting was that the column descriptor is able to find the data source,
315 // by traveling up the parent hierarchy until there's an XDataSource. This didn't work (which
316 // for instance causes #i65023#). We need another way to properly ensure this.
317
318 notifyDataSourceModified();
319 }
320
321 //........................................................................
322 } // namespace dbaccess
323 //........................................................................
324
325