xref: /trunk/main/ucb/source/ucp/package/pkgprovider.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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_pkg.hxx"
26 
27 /**************************************************************************
28                                 TODO
29  **************************************************************************
30 
31  *************************************************************************/
32 
33 #include <hash_map>
34 #include <osl/diagnose.h>
35 #include <cppuhelper/weak.hxx>
36 #include <ucbhelper/contentidentifier.hxx>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include "pkgprovider.hxx"
39 #include "pkgcontent.hxx"
40 #include "pkguri.hxx"
41 
42 using namespace com::sun::star;
43 
44 namespace package_ucp
45 {
46 
47 //=========================================================================
48 //
49 // class Package.
50 //
51 //=========================================================================
52 
53 class Package : public cppu::OWeakObject,
54                 public container::XHierarchicalNameAccess
55 {
56     friend class ContentProvider;
57 
58     rtl::OUString                                        m_aName;
59     uno::Reference< container::XHierarchicalNameAccess > m_xNA;
60     ContentProvider*                                     m_pOwner;
61 
62 public:
Package(const rtl::OUString & rName,const uno::Reference<container::XHierarchicalNameAccess> & xNA,ContentProvider * pOwner)63     Package( const rtl::OUString& rName,
64              const uno::Reference< container::XHierarchicalNameAccess > & xNA,
65              ContentProvider* pOwner )
66     : m_aName( rName ), m_xNA( xNA ), m_pOwner( pOwner ) {}
~Package()67     virtual ~Package() { m_pOwner->removePackage( m_aName ); }
68 
69     // XInterface
70     virtual uno::Any SAL_CALL
queryInterface(const uno::Type & aType)71     queryInterface( const uno::Type& aType )
72     { return m_xNA->queryInterface( aType ); }
73     virtual void SAL_CALL
acquire()74     acquire() throw()
75     { OWeakObject::acquire(); }
76     virtual void SAL_CALL
release()77     release() throw()
78     { OWeakObject::release(); }
79 
80     // XHierarchicalNameAccess
81     virtual uno::Any SAL_CALL
getByHierarchicalName(const rtl::OUString & aName)82     getByHierarchicalName( const rtl::OUString& aName )
83     { return m_xNA->getByHierarchicalName( aName ); }
84     virtual sal_Bool SAL_CALL
hasByHierarchicalName(const rtl::OUString & aName)85     hasByHierarchicalName( const rtl::OUString& aName )
86     { return m_xNA->hasByHierarchicalName( aName ); }
87 };
88 
89 //=========================================================================
90 //
91 // Packages.
92 //
93 //=========================================================================
94 
95 struct equalString
96 {
operator ()package_ucp::equalString97     bool operator()(
98         const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const
99     {
100         return !!( rKey1 == rKey2 );
101     }
102 };
103 
104 struct hashString
105 {
operator ()package_ucp::hashString106     size_t operator()( const rtl::OUString & rName ) const
107     {
108         return rName.hashCode();
109     }
110 };
111 
112 typedef std::hash_map
113 <
114     rtl::OUString,
115     Package*,
116     hashString,
117     equalString
118 >
119 PackageMap;
120 
121 class Packages : public PackageMap {};
122 
123 }
124 
125 using namespace package_ucp;
126 
127 //=========================================================================
128 //=========================================================================
129 //
130 // ContentProvider Implementation.
131 //
132 //=========================================================================
133 //=========================================================================
134 
ContentProvider(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)135 ContentProvider::ContentProvider(
136             const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
137 : ::ucbhelper::ContentProviderImplHelper( rSMgr ),
138   m_pPackages( 0 )
139 {
140 }
141 
142 //=========================================================================
143 // virtual
~ContentProvider()144 ContentProvider::~ContentProvider()
145 {
146     delete m_pPackages;
147 }
148 
149 //=========================================================================
150 //
151 // XInterface methods.
152 //
153 //=========================================================================
154 
155 XINTERFACE_IMPL_3( ContentProvider,
156                    lang::XTypeProvider,
157                    lang::XServiceInfo,
158                    ucb::XContentProvider );
159 
160 //=========================================================================
161 //
162 // XTypeProvider methods.
163 //
164 //=========================================================================
165 
166 XTYPEPROVIDER_IMPL_3( ContentProvider,
167                       lang::XTypeProvider,
168                       lang::XServiceInfo,
169                       ucb::XContentProvider );
170 
171 //=========================================================================
172 //
173 // XServiceInfo methods.
174 //
175 //=========================================================================
176 
177 XSERVICEINFO_IMPL_1( ContentProvider,
178                      rtl::OUString::createFromAscii(
179                         "com.sun.star.comp.ucb.PackageContentProvider" ),
180                      rtl::OUString::createFromAscii(
181                         PACKAGE_CONTENT_PROVIDER_SERVICE_NAME ) );
182 
183 //=========================================================================
184 //
185 // Service factory implementation.
186 //
187 //=========================================================================
188 
189 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
190 
191 //=========================================================================
192 //
193 // XContentProvider methods.
194 //
195 //=========================================================================
196 
197 // virtual
queryContent(const uno::Reference<ucb::XContentIdentifier> & Identifier)198 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
199             const uno::Reference< ucb::XContentIdentifier >& Identifier )
200 {
201     if ( !Identifier.is() )
202         return uno::Reference< ucb::XContent >();
203 
204     PackageUri aUri( Identifier->getContentIdentifier() );
205     if ( !aUri.isValid() )
206         throw ucb::IllegalIdentifierException();
207 
208     // Create a new identifier for the mormalized URL returned by
209     // PackageUri::getUri().
210     uno::Reference< ucb::XContentIdentifier > xId
211                 = new ::ucbhelper::ContentIdentifier( m_xSMgr, aUri.getUri() );
212 
213     osl::MutexGuard aGuard( m_aMutex );
214 
215     // Check, if a content with given id already exists...
216     uno::Reference< ucb::XContent > xContent
217         = queryExistingContent( xId ).get();
218     if ( xContent.is() )
219         return xContent;
220 
221     // Create a new content.
222 
223     xContent = Content::create( m_xSMgr, this, Identifier ); // not xId!!!
224     registerNewContent( xContent );
225 
226     if ( xContent.is() && !xContent->getIdentifier().is() )
227         throw ucb::IllegalIdentifierException();
228 
229     return xContent;
230 }
231 
232 //=========================================================================
233 //
234 // Other methods.
235 //
236 //=========================================================================
237 
238 uno::Reference< container::XHierarchicalNameAccess >
createPackage(const rtl::OUString & rName,const rtl::OUString & rParam)239 ContentProvider::createPackage( const rtl::OUString & rName, const rtl::OUString & rParam )
240 {
241     osl::MutexGuard aGuard( m_aMutex );
242 
243     if ( !rName.getLength() )
244     {
245         OSL_ENSURE( sal_False,
246                     "ContentProvider::createPackage - Invalid URL!" );
247         return uno::Reference< container::XHierarchicalNameAccess >();
248     }
249 
250     rtl::OUString rURL = rName + rParam;
251 
252     if ( m_pPackages )
253     {
254         Packages::const_iterator it = m_pPackages->find( rURL );
255         if ( it != m_pPackages->end() )
256         {
257             // Already instantiated. Return package.
258             return (*it).second->m_xNA;
259         }
260     }
261     else
262         m_pPackages = new Packages;
263 
264     // Create new package...
265     try
266     {
267         uno::Sequence< uno::Any > aArguments( 1 );
268         aArguments[ 0 ] <<= rURL;
269 
270         uno::Reference< uno::XInterface > xIfc
271             = m_xSMgr->createInstanceWithArguments(
272                 rtl::OUString::createFromAscii(
273                                 "com.sun.star.packages.comp.ZipPackage" ),
274                 aArguments );
275 
276         if ( xIfc.is() )
277         {
278             uno::Reference<
279                 container::XHierarchicalNameAccess > xNameAccess(
280                                                         xIfc, uno::UNO_QUERY );
281 
282             OSL_ENSURE( xNameAccess.is(),
283                         "ContentProvider::createPackage - "
284                         "Got no hierarchical name access!" );
285 
286             rtl::Reference< Package> xPackage
287                 = new Package( rURL, xNameAccess, this );
288 
289             (*m_pPackages)[ rURL ] = xPackage.get();
290 
291             return xPackage.get();
292         }
293     }
294     catch ( uno::RuntimeException const & )
295     {
296         // createInstanceWithArguemts
297     }
298     catch ( uno::Exception const & )
299     {
300         // createInstanceWithArguemts
301     }
302 
303     return uno::Reference< container::XHierarchicalNameAccess >();
304 }
305 
306 //=========================================================================
removePackage(const rtl::OUString & rName)307 sal_Bool ContentProvider::removePackage( const rtl::OUString & rName )
308 {
309     osl::MutexGuard aGuard( m_aMutex );
310 
311     if ( m_pPackages )
312     {
313         Packages::iterator it = m_pPackages->find( rName );
314         if ( it != m_pPackages->end() )
315         {
316             m_pPackages->erase( it );
317             return sal_True;
318         }
319     }
320     return sal_False;
321 }
322