1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
32 - change "singleton" behaviour by using new helper ::comhelper::SingletonRef
33 - rename method exist() to existHandlerForURL() or similar one
34 - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?!
37 //_________________________________________________________________________________________________________________
39 //_________________________________________________________________________________________________________________
41 #include <classes/protocolhandlercache.hxx>
42 #include <classes/converter.hxx>
43 #include <threadhelp/readguard.hxx>
44 #include <threadhelp/writeguard.hxx>
45 #include <threadhelp/lockhelper.hxx>
47 //_________________________________________________________________________________________________________________
49 //_________________________________________________________________________________________________________________
51 //_________________________________________________________________________________________________________________
53 //_________________________________________________________________________________________________________________
54 #include <tools/wldcrd.hxx>
55 #include <unotools/configpathes.hxx>
56 #include <rtl/ustrbuf.hxx>
58 //_________________________________________________________________________________________________________________
60 //_________________________________________________________________________________________________________________
64 //_________________________________________________________________________________________________________________
66 //_________________________________________________________________________________________________________________
68 //_________________________________________________________________________________________________________________
69 // non exported definitions
70 //_________________________________________________________________________________________________________________
73 @short overloaded index operator of hash map to support pattern key search
74 @descr All keys inside this hash map are URL pattern which points to an uno
75 implementation name of a protocol handler service which is registered
76 for this pattern. This operator makes it easy to find such registered
77 handler by using a full qualified URL and compare it with all pattern
81 the full qualified URL which should match to a registered pattern
83 @return An iterator which points to the found item inside the hash or PatternHash::end()
84 if no pattern match this given <var>sURL</var>.
86 @modified 30.04.2002 09:52, as96863
88 PatternHash::iterator
PatternHash::findPatternKey( const ::rtl::OUString
& sURL
)
90 PatternHash::iterator pItem
= this->begin();
91 while( pItem
!=this->end() )
93 WildCard
aPattern(pItem
->first
);
94 if (aPattern
.Matches(sURL
))
101 //_________________________________________________________________________________________________________________
104 @short initialize static member of class HandlerCache
105 @descr We use a singleton pattern to implement this handler cache.
106 That means it use two static member list to hold all neccessary informations
107 and a ref count mechanism to create/destroy it on demand.
109 @modified 30.04.2002 11:13, as96863
111 HandlerHash
* HandlerCache::m_pHandler
= NULL
;
112 PatternHash
* HandlerCache::m_pPattern
= NULL
;
113 sal_Int32
HandlerCache::m_nRefCount
= 0 ;
114 HandlerCFGAccess
* HandlerCache::m_pConfig
= NULL
;
116 //_________________________________________________________________________________________________________________
119 @short ctor of the cache of all registered protoco handler
120 @descr It tries to open the right configuration package automaticly
121 and fill the internal structures. After that the cache can be
122 used for read access on this data and perform some search
125 @modified 30.04.2002 10:02, as96863
127 HandlerCache::HandlerCache()
130 WriteGuard
aGlobalLock( LockHelper::getGlobalLock() );
134 m_pHandler
= new HandlerHash();
135 m_pPattern
= new PatternHash();
136 m_pConfig
= new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER
);
137 m_pConfig
->read(&m_pHandler
,&m_pPattern
);
138 m_pConfig
->setCache(this);
145 //_________________________________________________________________________________________________________________
148 @short dtor of the cache
149 @descr It frees all used memory. In further implementations (may if we support write access too)
150 it's a good place to flush changes back to the configuration - but not needed yet.
152 @modified 30.04.2002 09:54, as96863
154 HandlerCache::~HandlerCache()
157 WriteGuard
aGlobalLock( LockHelper::getGlobalLock() );
161 m_pConfig
->setCache(NULL
);
177 //_________________________________________________________________________________________________________________
180 @short dtor of the cache
181 @descr It frees all used memory. In further implementations (may if we support write access too)
182 it's a good place to flush changes back to the configuration - but not needed yet.
184 @modified 30.04.2002 09:54, as96863
186 sal_Bool
HandlerCache::search( const ::rtl::OUString
& sURL
, ProtocolHandler
* pReturn
) const
188 sal_Bool bFound
= sal_False
;
190 ReadGuard
aReadLock( LockHelper::getGlobalLock() );
191 PatternHash::const_iterator pItem
= m_pPattern
->findPatternKey(sURL
);
192 if (pItem
!=m_pPattern
->end())
194 *pReturn
= (*m_pHandler
)[pItem
->second
];
201 //_________________________________________________________________________________________________________________
204 @short search for a registered handler by using an URL struct
205 @descr We combine neccessary parts of this struct to a valid URL string
206 and call our other search method ...
207 It's a helper for outside code.
209 @modified 30.04.2002 09:54, as96863
211 sal_Bool
HandlerCache::search( const css::util::URL
& aURL
, ProtocolHandler
* pReturn
) const
213 return search( aURL
.Complete
, pReturn
);
216 //_________________________________________________________________________________________________________________
218 sal_Bool
HandlerCache::exists( const ::rtl::OUString
& sURL
) const
220 sal_Bool bFound
= sal_False
;
222 ReadGuard
aReadLock( LockHelper::getGlobalLock() );
223 PatternHash::const_iterator pItem
= m_pPattern
->findPatternKey(sURL
);
224 bFound
= pItem
!=m_pPattern
->end();
229 //_________________________________________________________________________________________________________________
230 void HandlerCache::takeOver(HandlerHash
* pHandler
, PatternHash
* pPattern
)
233 WriteGuard
aWriteLock( LockHelper::getGlobalLock() );
235 HandlerHash
* pOldHandler
= m_pHandler
;
236 PatternHash
* pOldPattern
= m_pPattern
;
238 m_pHandler
= pHandler
;
239 m_pPattern
= pPattern
;
250 //_________________________________________________________________________________________________________________
253 @short dtor of the config access class
254 @descr It opens the configuration package automaticly by using base class mechanism.
255 After that "read()" method of this class should be called to use it.
258 specifies the package name of the configuration data which should be used
260 @modified 30.04.2002 10:06, as96863
262 HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString
& sPackage
)
263 : ConfigItem( sPackage
)
265 css::uno::Sequence
< ::rtl::OUString
> lListenPathes(1);
266 lListenPathes
[0] = SETNAME_HANDLER
;
267 EnableNotification(lListenPathes
);
270 //_________________________________________________________________________________________________________________
273 @short use base class mechanism to fill given structures
274 @descr User use us as a wrapper between configuration api and his internal structures.
275 He give us some pointer to his member and we fill it.
278 pointer to a list of protocol handler infos
281 reverse map of handler pattern to her uno names
283 @modified 30.04.2002 09:54, as96863
285 void HandlerCFGAccess::read( HandlerHash
** ppHandler
,
286 PatternHash
** ppPattern
)
288 // list of all uno implementation names without encoding
289 css::uno::Sequence
< ::rtl::OUString
> lNames
= GetNodeNames( SETNAME_HANDLER
, ::utl::CONFIG_NAME_LOCAL_PATH
);
290 sal_Int32 nSourceCount
= lNames
.getLength();
291 sal_Int32 nTargetCount
= nSourceCount
;
292 // list of all full qualified path names of configuration entries
293 css::uno::Sequence
< ::rtl::OUString
> lFullNames ( nTargetCount
);
295 // expand names to full path names
298 for( nSource
=0; nSource
<nSourceCount
; ++nSource
)
300 ::rtl::OUStringBuffer
sPath( SETNAME_HANDLER
);
301 sPath
.append(CFG_PATH_SEPERATOR
);
302 sPath
.append(lNames
[nSource
]);
303 sPath
.append(CFG_PATH_SEPERATOR
);
304 sPath
.append(PROPERTY_PROTOCOLS
);
306 lFullNames
[nTarget
] = sPath
.makeStringAndClear();
311 css::uno::Sequence
< css::uno::Any
> lValues
= GetProperties( lFullNames
);
312 LOG_ASSERT2( lFullNames
.getLength()!=lValues
.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" )
316 for( nTarget
=0; nTarget
<nTargetCount
; ++nTarget
)
318 // create it new for every loop to guarantee a real empty object!
319 ProtocolHandler aHandler
;
320 aHandler
.m_sUNOName
= ::utl::extractFirstFromConfigurationPath(lNames
[nSource
]);
322 // unpack all values of this handler
323 css::uno::Sequence
< ::rtl::OUString
> lTemp
;
324 lValues
[nTarget
] >>= lTemp
;
325 aHandler
.m_lProtocols
= Converter::convert_seqOUString2OUStringList(lTemp
);
327 // register his pattern into the performance search hash
328 for (OUStringList::iterator pItem
=aHandler
.m_lProtocols
.begin();
329 pItem
!=aHandler
.m_lProtocols
.end() ;
332 (**ppPattern
)[*pItem
] = lNames
[nSource
];
335 // �nsert the handler info into the normal handler cache
336 (**ppHandler
)[lNames
[nSource
]] = aHandler
;
341 //_________________________________________________________________________________________________________________
342 void HandlerCFGAccess::Notify(const css::uno::Sequence
< rtl::OUString
>& /*lPropertyNames*/)
344 HandlerHash
* pHandler
= new HandlerHash
;
345 PatternHash
* pPattern
= new PatternHash
;
347 read(&pHandler
, &pPattern
);
349 m_pCache
->takeOver(pHandler
, pPattern
);
357 void HandlerCFGAccess::Commit()
361 } // namespace framework