1*6d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*6d739b60SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*6d739b60SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*6d739b60SAndrew Rist  * distributed with this work for additional information
6*6d739b60SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*6d739b60SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*6d739b60SAndrew Rist  * "License"); you may not use this file except in compliance
9*6d739b60SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*6d739b60SAndrew Rist  *
11*6d739b60SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*6d739b60SAndrew Rist  *
13*6d739b60SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*6d739b60SAndrew Rist  * software distributed under the License is distributed on an
15*6d739b60SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6d739b60SAndrew Rist  * KIND, either express or implied.  See the License for the
17*6d739b60SAndrew Rist  * specific language governing permissions and limitations
18*6d739b60SAndrew Rist  * under the License.
19*6d739b60SAndrew Rist  *
20*6d739b60SAndrew Rist  *************************************************************/
21*6d739b60SAndrew Rist 
22*6d739b60SAndrew 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  */
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.
102cdf0e10cSrcweir                 That means it use two static member list to hold all neccessary 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
116cdf0e10cSrcweir     @descr      It tries to open the right configuration package automaticly
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  */
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  */
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  */
182cdf0e10cSrcweir 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
201cdf0e10cSrcweir     @descr      We combine neccessary 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  */
207cdf0e10cSrcweir sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
208cdf0e10cSrcweir {
209cdf0e10cSrcweir     return search( aURL.Complete, pReturn );
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir //_________________________________________________________________________________________________________________
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 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 //_________________________________________________________________________________________________________________
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
250cdf0e10cSrcweir     @descr      It opens the configuration package automaticly 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  */
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  */
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 //_________________________________________________________________________________________________________________
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 
353cdf0e10cSrcweir void HandlerCFGAccess::Commit()
354cdf0e10cSrcweir {
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir } // namespace framework
358