1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef DBAUI_DATASOURCEMAP_HXX
29 #define DBAUI_DATASOURCEMAP_HXX
30 
31 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #endif
34 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #endif
37 #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #endif
40 #ifndef _COMPHELPER_STLTYPES_HXX_
41 #include <comphelper/stl_types.hxx>
42 #endif
43 #ifndef _STRING_HXX
44 #include <tools/string.hxx>
45 #endif
46 
47 class SfxItemPool;
48 class SfxItemSet;
49 //.........................................................................
50 namespace dbaui
51 {
52 //.........................................................................
53 
54 	//=====================================================================
55 	//= ODatasourceMap
56 	//=====================================================================
57 	class ODatasourceMap
58 	{
59 		struct DatasourceInfo
60 		{
61 			::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
62 								xDatasource;
63 			SfxItemSet*			pModifications;
64 
65 			DatasourceInfo() :pModifications (NULL) {  }
66 			DatasourceInfo(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxDS,
67 					SfxItemSet* _pMods = NULL)
68 				:xDatasource(_rxDS), pModifications(_pMods) { }
69 		};
70 
71 		::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
72 								m_xORB;					/// service factory
73 		::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
74 								m_xDatabaseContext;		/// database context we're working in
75 
76 		DECLARE_STL_USTRINGACCESS_MAP(DatasourceInfo, DatasourceInfos);
77 		DatasourceInfos			m_aDatasources;			/// known infos about data sources
78 
79 		// deleted data sources, not necessarily with distinct names, that's why accessed via unique ids
80 		DECLARE_STL_MAP(sal_Int32, DatasourceInfo, ::std::less< sal_Int32 >, MapInt2Info);
81 		MapInt2Info				m_aDeletedDatasources;
82 
83 	public:
84 		/// iterating through all data sources
85 		class Iterator;
86 		friend class ODatasourceMap::Iterator;
87 
88 		/// encapsulates the infos about a data source for access from outside the class
89 		class ODatasourceInfo;
90 		friend class ODatasourceMap::ODatasourceInfo;
91 
92 		ODatasourceInfo operator[](const ::rtl::OUString _rName);
93 
94 		ODatasourceMap(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > _rxORB);
95 
96 		// get the database context
97 		::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
98 					getContext() { return m_xDatabaseContext; }
99 
100 		/// first element for iterating through the datasources
101 		Iterator	begin();
102 		/// last element for iterating through the datasources
103 		Iterator	end();
104 
105 		/// first element for iterating through the deleted datasources
106 		Iterator	beginDeleted();
107 		/// last element for iterating through the deleted datasources
108 		Iterator	endDeleted();
109 
110 		/// check if the object contains a valid datasource enumeration
111 		sal_Bool	isValid() const { return m_xDatabaseContext.is(); }
112 		/// check if a datasource with the given name exists
113 		sal_Bool	exists(const ::rtl::OUString& _rName) const;
114 		/// return the number of datasources available
115 		sal_Int32	size() const { return m_aDatasources.size(); }
116 		/// clear the map (non-deleted <em>and</em> deleted items)
117 		void		clear();
118 		/// clear the map (deleted items only)
119 		void		clearDeleted();
120 
121 		/// clear the modification items for a datasource
122 		void		clearModifiedFlag(const ::rtl::OUString& _rName);
123 
124 		/** tell the map that a data source is scheduled to be deleted.
125 			@return		id for accessing the deleted data source later. -1 if no free id existed or an error occured
126 		*/
127 		sal_Int32	markDeleted(const ::rtl::OUString& _rName);
128 
129 		/** restores a datasource which has previously been marked as deleted.<p/>
130 			@param		_nAccessId		the access id as got from <method>markDeleted</method>
131 			@param		_rName			contains, upon return, the name of the datasource the access key refers to
132 			@return		sal_True if the datasource was successfully restored, sal_False if it could not be restored
133 						because of a naming conflict (e.g. because another data source now has the name of the
134 						to-be-restored one).
135 			@see	renamed
136 			@see	markDeleted
137 		*/
138 		sal_Bool	restoreDeleted(sal_Int32 _nAccessId, ::rtl::OUString& _rName);
139 
140 		/// remove an element from the map
141 		void		deleted(const ::rtl::OUString& _rName);
142 			// (should be an erase(const Iterator&), but this is way to general ...
143 
144 		/// update the infos for a data source with a given item set
145 		void		update(const ::rtl::OUString& _rName, SfxItemSet& _rSet);
146 		/** Tells the map that an entry has been renamed in a sense that it should be accessible under
147 			a new name. This does not necesssarily mean that the data source has been renamed within
148 			it's database context
149 		*/
150 		void		renamed(const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName);
151 
152 		/** adjust the registration name if necessary<p/>
153 			The real name of the data source (as indicated in the SfxItemSet for this ds) may be another
154 			one than the name the ds is registered for. This method corrects this, the ds will become registered
155 			under it's real name.
156 			@param		_rName		the name the ds is registered for
157 			@return					the real name of the data source
158 		*/
159 		::rtl::OUString adjustRealName(const ::rtl::OUString& _rName);
160 
161 	protected:
162 		/** ensure that the DatabaseInfo for the named object is filled<p/>
163 			This method allows us lazy access to the data sources: They're retrieved from the context
164 			only if they're accessed by somebody.
165 		*/
166 		void	ensureObject(const ::rtl::OUString& _rName);
167 	};
168 
169 	//-------------------------------------------------------------------------
170 	//- ODatasourceMap::ODatasourceInfo
171 	//-------------------------------------------------------------------------
172 	class ODatasourceMap::ODatasourceInfo
173 	{
174 		friend class ODatasourceMap;
175 		friend class ODatasourceMap::Iterator;
176 
177 	private:
178 		ODatasourceMap*								m_pOwner;
179 		const ODatasourceMap::DatasourceInfo&		m_rInfoImpl;
180 		::rtl::OUString								m_sName;
181 		sal_Int32									m_nAccessKey;
182 
183 	public:
184 		ODatasourceInfo(const ODatasourceInfo& _rSource)
185 			:m_pOwner(_rSource.m_pOwner), m_sName(_rSource.m_sName), m_rInfoImpl(_rSource.m_rInfoImpl), m_nAccessKey(_rSource.m_nAccessKey) { }
186 
187 		/// check if the datasource settings are modified
188 		sal_Bool		isModified() const;
189 		/// get the name the datasource is registered under
190 		::rtl::OUString	getName() const { return m_sName; }
191 		/// get the original name of a datasource (may habe been renamed)
192 		::rtl::OUString	getOriginalName() const;
193 		/// get the real name of the datasource, which is the name which is in the item set
194 		::rtl::OUString	getRealName() const;
195 		/// check if the datasource should is about to be renamed (which means the original name does not equal the real name
196 		sal_Bool		isRenamed() const { return !getRealName().equals(getOriginalName()); }
197 		/// get the key used to acces the object in the data source map
198 		sal_Int32		getAccessKey() const { return m_nAccessKey; }
199 
200 		/// return the datasource the object represents
201 		::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
202 						getDatasource() const;
203 		/** return the modifications for the data source<p/>
204 			The return value is non-NULL if and only if <method>isModified</method> returned sal_True
205 		*/
206 		const SfxItemSet*
207 						getModifications() const { return m_rInfoImpl.pModifications; }
208 
209 		operator ::rtl::OUString() const { return getName(); }
210 		operator String() const { return getName().getStr(); }
211 
212 		const ODatasourceInfo* const operator->() const { return this; }
213 
214 	protected:
215 		ODatasourceInfo(
216 				ODatasourceMap* _pOwner, const ::rtl::OUString& _rName,
217 				const ODatasourceMap::DatasourceInfo& _rSource, sal_Int32 _nAccessKey)
218 			:m_pOwner(_pOwner), m_sName(_rName), m_rInfoImpl(_rSource), m_nAccessKey(_nAccessKey) { }
219 	};
220 
221 	//-------------------------------------------------------------------------
222 	//- ODatasourceMap::Iterator
223 	//-------------------------------------------------------------------------
224 	class ODatasourceMap::Iterator
225 	{
226 		friend class ODatasourceMap;
227 	protected:
228 		ODatasourceMap*									m_pOwner;
229 		ODatasourceMap::ConstDatasourceInfosIterator	m_aPos;
230 		ODatasourceMap::ConstMapInt2InfoIterator		m_aPosDeleted;
231 		sal_Bool										m_bLoopingDeleted;
232 
233 	public:
234 		Iterator(const Iterator& _rSource);
235 
236 		ODatasourceInfo operator->() const;
237 		ODatasourceInfo operator*() const;
238 
239 		/// prefix increment
240 		const Iterator&	operator++();
241 		/// postfix increment
242 		const Iterator	operator++(int) { Iterator hold(*this); ++*this; return hold; }
243 
244 		/// prefix decrement
245 		const Iterator&	operator--();
246 		/// postfix decrement
247 		const Iterator	operator--(int) { Iterator hold(*this); --*this; return hold; }
248 
249 
250 	// compare two iterators
251 		friend bool operator==(const Iterator& lhs, const Iterator& rhs)
252 		{
253 			if (lhs.m_bLoopingDeleted)
254 				return lhs.m_aPosDeleted == rhs.m_aPosDeleted;
255 			else
256 				return lhs.m_aPos == rhs.m_aPos;
257 		}
258 
259 		friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return !(lhs == rhs); }
260 
261 	protected:
262 		Iterator(ODatasourceMap* _pOwner, ODatasourceMap::ConstDatasourceInfosIterator _rPos);
263 		Iterator(ODatasourceMap* _pOwner, ODatasourceMap::ConstMapInt2InfoIterator _rPos);
264 
265 	protected:
266 		::rtl::OUString implGetName(const ODatasourceMap::DatasourceInfo& _rInfo) const;
267 	};
268 
269 //.........................................................................
270 }	// namespace dbaui
271 //.........................................................................
272 
273 #endif // DBAUI_DATASOURCEMAP_HXX
274 
275