16d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
36d739b60SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
46d739b60SAndrew Rist * or more contributor license agreements. See the NOTICE file
56d739b60SAndrew Rist * distributed with this work for additional information
66d739b60SAndrew Rist * regarding copyright ownership. The ASF licenses this file
76d739b60SAndrew Rist * to you under the Apache License, Version 2.0 (the
86d739b60SAndrew Rist * "License"); you may not use this file except in compliance
96d739b60SAndrew Rist * with the License. You may obtain a copy of the License at
106d739b60SAndrew Rist *
116d739b60SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
126d739b60SAndrew Rist *
136d739b60SAndrew Rist * Unless required by applicable law or agreed to in writing,
146d739b60SAndrew Rist * software distributed under the License is distributed on an
156d739b60SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
166d739b60SAndrew Rist * KIND, either express or implied. See the License for the
176d739b60SAndrew Rist * specific language governing permissions and limitations
186d739b60SAndrew Rist * under the License.
196d739b60SAndrew Rist *
206d739b60SAndrew Rist *************************************************************/
216d739b60SAndrew Rist
226d739b60SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir /*TODO
28cdf0e10cSrcweir - change "singleton" behaviour by using new helper ::comhelper::SingletonRef
29cdf0e10cSrcweir - rename method exist() to existHandlerForURL() or similar one
30cdf0e10cSrcweir - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?!
31cdf0e10cSrcweir */
32cdf0e10cSrcweir
33cdf0e10cSrcweir //_________________________________________________________________________________________________________________
34cdf0e10cSrcweir // my own includes
35cdf0e10cSrcweir //_________________________________________________________________________________________________________________
36cdf0e10cSrcweir
37cdf0e10cSrcweir #include <classes/protocolhandlercache.hxx>
38cdf0e10cSrcweir #include <classes/converter.hxx>
39cdf0e10cSrcweir #include <threadhelp/readguard.hxx>
40cdf0e10cSrcweir #include <threadhelp/writeguard.hxx>
41cdf0e10cSrcweir #include <threadhelp/lockhelper.hxx>
42cdf0e10cSrcweir
43cdf0e10cSrcweir //_________________________________________________________________________________________________________________
44cdf0e10cSrcweir // interface includes
45cdf0e10cSrcweir //_________________________________________________________________________________________________________________
46cdf0e10cSrcweir
47cdf0e10cSrcweir //_________________________________________________________________________________________________________________
48cdf0e10cSrcweir // other includes
49cdf0e10cSrcweir //_________________________________________________________________________________________________________________
50cdf0e10cSrcweir #include <tools/wldcrd.hxx>
51cdf0e10cSrcweir #include <unotools/configpathes.hxx>
52cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
53cdf0e10cSrcweir
54cdf0e10cSrcweir //_________________________________________________________________________________________________________________
55cdf0e10cSrcweir // namespace
56cdf0e10cSrcweir //_________________________________________________________________________________________________________________
57cdf0e10cSrcweir
58cdf0e10cSrcweir namespace framework{
59cdf0e10cSrcweir
60cdf0e10cSrcweir //_________________________________________________________________________________________________________________
61cdf0e10cSrcweir // non exported const
62cdf0e10cSrcweir //_________________________________________________________________________________________________________________
63cdf0e10cSrcweir
64cdf0e10cSrcweir //_________________________________________________________________________________________________________________
65cdf0e10cSrcweir // non exported definitions
66cdf0e10cSrcweir //_________________________________________________________________________________________________________________
67cdf0e10cSrcweir
68cdf0e10cSrcweir /**
69cdf0e10cSrcweir @short overloaded index operator of hash map to support pattern key search
70cdf0e10cSrcweir @descr All keys inside this hash map are URL pattern which points to an uno
71cdf0e10cSrcweir implementation name of a protocol handler service which is registered
72cdf0e10cSrcweir for this pattern. This operator makes it easy to find such registered
73cdf0e10cSrcweir handler by using a full qualified URL and compare it with all pattern
74cdf0e10cSrcweir keys.
75cdf0e10cSrcweir
76cdf0e10cSrcweir @param sURL
77cdf0e10cSrcweir the full qualified URL which should match to a registered pattern
78cdf0e10cSrcweir
79cdf0e10cSrcweir @return An iterator which points to the found item inside the hash or PatternHash::end()
80cdf0e10cSrcweir if no pattern match this given <var>sURL</var>.
81cdf0e10cSrcweir
82cdf0e10cSrcweir @modified 30.04.2002 09:52, as96863
83cdf0e10cSrcweir */
findPatternKey(const::rtl::OUString & sURL)84cdf0e10cSrcweir PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL )
85cdf0e10cSrcweir {
86cdf0e10cSrcweir PatternHash::iterator pItem = this->begin();
87cdf0e10cSrcweir while( pItem!=this->end() )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir WildCard aPattern(pItem->first);
90cdf0e10cSrcweir if (aPattern.Matches(sURL))
91cdf0e10cSrcweir break;
92cdf0e10cSrcweir ++pItem;
93cdf0e10cSrcweir }
94cdf0e10cSrcweir return pItem;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir
97cdf0e10cSrcweir //_________________________________________________________________________________________________________________
98cdf0e10cSrcweir
99cdf0e10cSrcweir /**
100cdf0e10cSrcweir @short initialize static member of class HandlerCache
101cdf0e10cSrcweir @descr We use a singleton pattern to implement this handler cache.
102*07a3d7f1SPedro Giffuni That means it use two static member list to hold all necessary informations
103cdf0e10cSrcweir and a ref count mechanism to create/destroy it on demand.
104cdf0e10cSrcweir
105cdf0e10cSrcweir @modified 30.04.2002 11:13, as96863
106cdf0e10cSrcweir */
107cdf0e10cSrcweir HandlerHash* HandlerCache::m_pHandler = NULL;
108cdf0e10cSrcweir PatternHash* HandlerCache::m_pPattern = NULL;
109cdf0e10cSrcweir sal_Int32 HandlerCache::m_nRefCount = 0 ;
110cdf0e10cSrcweir HandlerCFGAccess* HandlerCache::m_pConfig = NULL;
111cdf0e10cSrcweir
112cdf0e10cSrcweir //_________________________________________________________________________________________________________________
113cdf0e10cSrcweir
114cdf0e10cSrcweir /**
115cdf0e10cSrcweir @short ctor of the cache of all registered protoco handler
116*07a3d7f1SPedro Giffuni @descr It tries to open the right configuration package automatically
117cdf0e10cSrcweir and fill the internal structures. After that the cache can be
118cdf0e10cSrcweir used for read access on this data and perform some search
119cdf0e10cSrcweir operations on it.
120cdf0e10cSrcweir
121cdf0e10cSrcweir @modified 30.04.2002 10:02, as96863
122cdf0e10cSrcweir */
HandlerCache()123cdf0e10cSrcweir HandlerCache::HandlerCache()
124cdf0e10cSrcweir {
125cdf0e10cSrcweir /* SAFE */{
126cdf0e10cSrcweir WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
127cdf0e10cSrcweir
128cdf0e10cSrcweir if (m_nRefCount==0)
129cdf0e10cSrcweir {
130cdf0e10cSrcweir m_pHandler = new HandlerHash();
131cdf0e10cSrcweir m_pPattern = new PatternHash();
132cdf0e10cSrcweir m_pConfig = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER);
133cdf0e10cSrcweir m_pConfig->read(&m_pHandler,&m_pPattern);
134cdf0e10cSrcweir m_pConfig->setCache(this);
135cdf0e10cSrcweir }
136cdf0e10cSrcweir
137cdf0e10cSrcweir ++m_nRefCount;
138cdf0e10cSrcweir /* SAFE */}
139cdf0e10cSrcweir }
140cdf0e10cSrcweir
141cdf0e10cSrcweir //_________________________________________________________________________________________________________________
142cdf0e10cSrcweir
143cdf0e10cSrcweir /**
144cdf0e10cSrcweir @short dtor of the cache
145cdf0e10cSrcweir @descr It frees all used memory. In further implementations (may if we support write access too)
146cdf0e10cSrcweir it's a good place to flush changes back to the configuration - but not needed yet.
147cdf0e10cSrcweir
148cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863
149cdf0e10cSrcweir */
~HandlerCache()150cdf0e10cSrcweir HandlerCache::~HandlerCache()
151cdf0e10cSrcweir {
152cdf0e10cSrcweir /* SAFE */{
153cdf0e10cSrcweir WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
154cdf0e10cSrcweir
155cdf0e10cSrcweir if( m_nRefCount==1)
156cdf0e10cSrcweir {
157cdf0e10cSrcweir m_pConfig->setCache(NULL);
158cdf0e10cSrcweir m_pHandler->free();
159cdf0e10cSrcweir m_pPattern->free();
160cdf0e10cSrcweir
161cdf0e10cSrcweir delete m_pConfig;
162cdf0e10cSrcweir delete m_pHandler;
163cdf0e10cSrcweir delete m_pPattern;
164cdf0e10cSrcweir m_pConfig = NULL;
165cdf0e10cSrcweir m_pHandler= NULL;
166cdf0e10cSrcweir m_pPattern= NULL;
167cdf0e10cSrcweir }
168cdf0e10cSrcweir
169cdf0e10cSrcweir --m_nRefCount;
170cdf0e10cSrcweir /* SAFE */}
171cdf0e10cSrcweir }
172cdf0e10cSrcweir
173cdf0e10cSrcweir //_________________________________________________________________________________________________________________
174cdf0e10cSrcweir
175cdf0e10cSrcweir /**
176cdf0e10cSrcweir @short dtor of the cache
177cdf0e10cSrcweir @descr It frees all used memory. In further implementations (may if we support write access too)
178cdf0e10cSrcweir it's a good place to flush changes back to the configuration - but not needed yet.
179cdf0e10cSrcweir
180cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863
181cdf0e10cSrcweir */
search(const::rtl::OUString & sURL,ProtocolHandler * pReturn) const182cdf0e10cSrcweir sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const
183cdf0e10cSrcweir {
184cdf0e10cSrcweir sal_Bool bFound = sal_False;
185cdf0e10cSrcweir /* SAFE */{
186cdf0e10cSrcweir ReadGuard aReadLock( LockHelper::getGlobalLock() );
187cdf0e10cSrcweir PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
188cdf0e10cSrcweir if (pItem!=m_pPattern->end())
189cdf0e10cSrcweir {
190cdf0e10cSrcweir *pReturn = (*m_pHandler)[pItem->second];
191cdf0e10cSrcweir bFound = sal_True;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir /* SAFE */}
194cdf0e10cSrcweir return bFound;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
197cdf0e10cSrcweir //_________________________________________________________________________________________________________________
198cdf0e10cSrcweir
199cdf0e10cSrcweir /**
200cdf0e10cSrcweir @short search for a registered handler by using an URL struct
201*07a3d7f1SPedro Giffuni @descr We combine necessary parts of this struct to a valid URL string
202cdf0e10cSrcweir and call our other search method ...
203cdf0e10cSrcweir It's a helper for outside code.
204cdf0e10cSrcweir
205cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863
206cdf0e10cSrcweir */
search(const css::util::URL & aURL,ProtocolHandler * pReturn) const207cdf0e10cSrcweir sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
208cdf0e10cSrcweir {
209cdf0e10cSrcweir return search( aURL.Complete, pReturn );
210cdf0e10cSrcweir }
211cdf0e10cSrcweir
212cdf0e10cSrcweir //_________________________________________________________________________________________________________________
213cdf0e10cSrcweir
exists(const::rtl::OUString & sURL) const214cdf0e10cSrcweir sal_Bool HandlerCache::exists( const ::rtl::OUString& sURL ) const
215cdf0e10cSrcweir {
216cdf0e10cSrcweir sal_Bool bFound = sal_False;
217cdf0e10cSrcweir /* SAFE */{
218cdf0e10cSrcweir ReadGuard aReadLock( LockHelper::getGlobalLock() );
219cdf0e10cSrcweir PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
220cdf0e10cSrcweir bFound = pItem!=m_pPattern->end();
221cdf0e10cSrcweir /* SAFE */}
222cdf0e10cSrcweir return bFound;
223cdf0e10cSrcweir }
224cdf0e10cSrcweir
225cdf0e10cSrcweir //_________________________________________________________________________________________________________________
takeOver(HandlerHash * pHandler,PatternHash * pPattern)226cdf0e10cSrcweir void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern)
227cdf0e10cSrcweir {
228cdf0e10cSrcweir // SAFE ->
229cdf0e10cSrcweir WriteGuard aWriteLock( LockHelper::getGlobalLock() );
230cdf0e10cSrcweir
231cdf0e10cSrcweir HandlerHash* pOldHandler = m_pHandler;
232cdf0e10cSrcweir PatternHash* pOldPattern = m_pPattern;
233cdf0e10cSrcweir
234cdf0e10cSrcweir m_pHandler = pHandler;
235cdf0e10cSrcweir m_pPattern = pPattern;
236cdf0e10cSrcweir
237cdf0e10cSrcweir pOldHandler->free();
238cdf0e10cSrcweir pOldPattern->free();
239cdf0e10cSrcweir delete pOldHandler;
240cdf0e10cSrcweir delete pOldPattern;
241cdf0e10cSrcweir
242cdf0e10cSrcweir aWriteLock.unlock();
243cdf0e10cSrcweir // <- SAFE
244cdf0e10cSrcweir }
245cdf0e10cSrcweir
246cdf0e10cSrcweir //_________________________________________________________________________________________________________________
247cdf0e10cSrcweir
248cdf0e10cSrcweir /**
249cdf0e10cSrcweir @short dtor of the config access class
250*07a3d7f1SPedro Giffuni @descr It opens the configuration package automatically by using base class mechanism.
251cdf0e10cSrcweir After that "read()" method of this class should be called to use it.
252cdf0e10cSrcweir
253cdf0e10cSrcweir @param sPackage
254cdf0e10cSrcweir specifies the package name of the configuration data which should be used
255cdf0e10cSrcweir
256cdf0e10cSrcweir @modified 30.04.2002 10:06, as96863
257cdf0e10cSrcweir */
HandlerCFGAccess(const::rtl::OUString & sPackage)258cdf0e10cSrcweir HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage )
259cdf0e10cSrcweir : ConfigItem( sPackage )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lListenPathes(1);
262cdf0e10cSrcweir lListenPathes[0] = SETNAME_HANDLER;
263cdf0e10cSrcweir EnableNotification(lListenPathes);
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir //_________________________________________________________________________________________________________________
267cdf0e10cSrcweir
268cdf0e10cSrcweir /**
269cdf0e10cSrcweir @short use base class mechanism to fill given structures
270cdf0e10cSrcweir @descr User use us as a wrapper between configuration api and his internal structures.
271cdf0e10cSrcweir He give us some pointer to his member and we fill it.
272cdf0e10cSrcweir
273cdf0e10cSrcweir @param pHandler
274cdf0e10cSrcweir pointer to a list of protocol handler infos
275cdf0e10cSrcweir
276cdf0e10cSrcweir @param pPattern
277cdf0e10cSrcweir reverse map of handler pattern to her uno names
278cdf0e10cSrcweir
279cdf0e10cSrcweir @modified 30.04.2002 09:54, as96863
280cdf0e10cSrcweir */
read(HandlerHash ** ppHandler,PatternHash ** ppPattern)281cdf0e10cSrcweir void HandlerCFGAccess::read( HandlerHash** ppHandler ,
282cdf0e10cSrcweir PatternHash** ppPattern )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir // list of all uno implementation names without encoding
285cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH );
286cdf0e10cSrcweir sal_Int32 nSourceCount = lNames.getLength();
287cdf0e10cSrcweir sal_Int32 nTargetCount = nSourceCount;
288cdf0e10cSrcweir // list of all full qualified path names of configuration entries
289cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount );
290cdf0e10cSrcweir
291cdf0e10cSrcweir // expand names to full path names
292cdf0e10cSrcweir sal_Int32 nSource=0;
293cdf0e10cSrcweir sal_Int32 nTarget=0;
294cdf0e10cSrcweir for( nSource=0; nSource<nSourceCount; ++nSource )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir ::rtl::OUStringBuffer sPath( SETNAME_HANDLER );
297cdf0e10cSrcweir sPath.append(CFG_PATH_SEPERATOR);
298cdf0e10cSrcweir sPath.append(lNames[nSource]);
299cdf0e10cSrcweir sPath.append(CFG_PATH_SEPERATOR);
300cdf0e10cSrcweir sPath.append(PROPERTY_PROTOCOLS);
301cdf0e10cSrcweir
302cdf0e10cSrcweir lFullNames[nTarget] = sPath.makeStringAndClear();
303cdf0e10cSrcweir ++nTarget;
304cdf0e10cSrcweir }
305cdf0e10cSrcweir
306cdf0e10cSrcweir // get values at all
307cdf0e10cSrcweir css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
308cdf0e10cSrcweir LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" )
309cdf0e10cSrcweir
310cdf0e10cSrcweir // fill structures
311cdf0e10cSrcweir nSource = 0;
312cdf0e10cSrcweir for( nTarget=0; nTarget<nTargetCount; ++nTarget )
313cdf0e10cSrcweir {
314cdf0e10cSrcweir // create it new for every loop to guarantee a real empty object!
315cdf0e10cSrcweir ProtocolHandler aHandler;
316cdf0e10cSrcweir aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
317cdf0e10cSrcweir
318cdf0e10cSrcweir // unpack all values of this handler
319cdf0e10cSrcweir css::uno::Sequence< ::rtl::OUString > lTemp;
320cdf0e10cSrcweir lValues[nTarget] >>= lTemp;
321cdf0e10cSrcweir aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp);
322cdf0e10cSrcweir
323cdf0e10cSrcweir // register his pattern into the performance search hash
324cdf0e10cSrcweir for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin();
325cdf0e10cSrcweir pItem!=aHandler.m_lProtocols.end() ;
326cdf0e10cSrcweir ++pItem )
327cdf0e10cSrcweir {
328cdf0e10cSrcweir (**ppPattern)[*pItem] = lNames[nSource];
329cdf0e10cSrcweir }
330cdf0e10cSrcweir
331cdf0e10cSrcweir // ï¿œnsert the handler info into the normal handler cache
332cdf0e10cSrcweir (**ppHandler)[lNames[nSource]] = aHandler;
333cdf0e10cSrcweir ++nSource;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir }
336cdf0e10cSrcweir
337cdf0e10cSrcweir //_________________________________________________________________________________________________________________
Notify(const css::uno::Sequence<rtl::OUString> &)338cdf0e10cSrcweir void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir HandlerHash* pHandler = new HandlerHash;
341cdf0e10cSrcweir PatternHash* pPattern = new PatternHash;
342cdf0e10cSrcweir
343cdf0e10cSrcweir read(&pHandler, &pPattern);
344cdf0e10cSrcweir if (m_pCache)
345cdf0e10cSrcweir m_pCache->takeOver(pHandler, pPattern);
346cdf0e10cSrcweir else
347cdf0e10cSrcweir {
348cdf0e10cSrcweir delete pHandler;
349cdf0e10cSrcweir delete pPattern;
350cdf0e10cSrcweir }
351cdf0e10cSrcweir }
352cdf0e10cSrcweir
Commit()353cdf0e10cSrcweir void HandlerCFGAccess::Commit()
354cdf0e10cSrcweir {
355cdf0e10cSrcweir }
356cdf0e10cSrcweir
357cdf0e10cSrcweir } // namespace framework
358