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_svl.hxx"
26
27 #include "fsfactory.hxx"
28 #include "cppuhelper/factory.hxx"
29 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
30 #include <com/sun/star/embed/ElementModes.hpp>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/io/XSeekable.hpp>
33
34
35 #include <ucbhelper/fileidentifierconverter.hxx>
36 #include <ucbhelper/contentbroker.hxx>
37 #include <ucbhelper/content.hxx>
38
39 #include <unotools/tempfile.hxx>
40 #include <unotools/ucbhelper.hxx>
41
42 #include "fsstorage.hxx"
43
44
45 using namespace ::com::sun::star;
46
47 //-------------------------------------------------------------------------
impl_staticGetSupportedServiceNames()48 uno::Sequence< ::rtl::OUString > SAL_CALL FSStorageFactory::impl_staticGetSupportedServiceNames()
49 {
50 uno::Sequence< ::rtl::OUString > aRet(2);
51 aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory");
52 aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.FileSystemStorageFactory");
53 return aRet;
54 }
55
56 //-------------------------------------------------------------------------
impl_staticGetImplementationName()57 ::rtl::OUString SAL_CALL FSStorageFactory::impl_staticGetImplementationName()
58 {
59 return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.FileSystemStorageFactory");
60 }
61
62 //-------------------------------------------------------------------------
impl_staticCreateSelfInstance(const uno::Reference<lang::XMultiServiceFactory> & xServiceManager)63 uno::Reference< uno::XInterface > SAL_CALL FSStorageFactory::impl_staticCreateSelfInstance(
64 const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
65 {
66 return uno::Reference< uno::XInterface >( *new FSStorageFactory( xServiceManager ) );
67 }
68
69 //-------------------------------------------------------------------------
createInstance()70 uno::Reference< uno::XInterface > SAL_CALL FSStorageFactory::createInstance()
71 throw ( uno::Exception,
72 uno::RuntimeException )
73 {
74 ::rtl::OUString aTempURL;
75
76 aTempURL = ::utl::TempFile( NULL, sal_True ).GetURL();
77
78 if ( !aTempURL.getLength() )
79 throw uno::RuntimeException(); // TODO: can not create tempfile
80
81 ::ucbhelper::Content aResultContent(
82 aTempURL, uno::Reference< ucb::XCommandEnvironment >() );
83
84 return uno::Reference< uno::XInterface >(
85 static_cast< OWeakObject* >(
86 new FSStorage( aResultContent,
87 embed::ElementModes::READWRITE,
88 uno::Sequence< beans::PropertyValue >(),
89 m_xFactory ) ),
90 uno::UNO_QUERY );
91 }
92
93 //-------------------------------------------------------------------------
createInstanceWithArguments(const uno::Sequence<uno::Any> & aArguments)94 uno::Reference< uno::XInterface > SAL_CALL FSStorageFactory::createInstanceWithArguments(
95 const uno::Sequence< uno::Any >& aArguments )
96 throw ( uno::Exception,
97 uno::RuntimeException )
98 {
99 // The request for storage can be done with up to three arguments
100
101 // The first argument specifies a source for the storage
102 // it must be URL.
103 // The second value is a mode the storage should be open in.
104 // And the third value is a media descriptor.
105
106 sal_Int32 nArgNum = aArguments.getLength();
107 OSL_ENSURE( nArgNum < 4, "Wrong parameter number" );
108
109 if ( !nArgNum )
110 return createInstance();
111
112 // first try to retrieve storage open mode if any
113 // by default the storage will be open in readonly mode
114 sal_Int32 nStorageMode = embed::ElementModes::READ;
115 if ( nArgNum >= 2 )
116 {
117 if( !( aArguments[1] >>= nStorageMode ) )
118 {
119 OSL_ENSURE( sal_False, "Wrong second argument!\n" );
120 throw uno::Exception(); // TODO: Illegal argument
121 }
122 // it's allways possible to read written storage in this implementation
123 nStorageMode |= embed::ElementModes::READ;
124 }
125
126 // retrieve storage source URL
127 ::rtl::OUString aURL;
128
129 if ( aArguments[0] >>= aURL )
130 {
131 if ( !aURL.getLength() )
132 {
133 OSL_ENSURE( sal_False, "Empty URL is provided!\n" );
134 throw uno::Exception(); // TODO: illegal argument
135 }
136 }
137 else
138 {
139 OSL_ENSURE( sal_False, "Wrong first argument!\n" );
140 throw uno::Exception(); // TODO: Illegal argument
141 }
142
143 // retrieve mediadescriptor and set storage properties
144 uno::Sequence< beans::PropertyValue > aDescr;
145 uno::Sequence< beans::PropertyValue > aPropsToSet;
146
147 if ( nArgNum >= 3 )
148 {
149 if( aArguments[2] >>= aDescr )
150 {
151 aPropsToSet.realloc(1);
152 aPropsToSet[0].Name = ::rtl::OUString::createFromAscii( "URL" );
153 aPropsToSet[0].Value <<= aURL;
154
155 for ( sal_Int32 nInd = 0, nNumArgs = 1; nInd < aDescr.getLength(); nInd++ )
156 {
157 if ( aDescr[nInd].Name.equalsAscii( "InteractionHandler" ) )
158 {
159 aPropsToSet.realloc( ++nNumArgs );
160 aPropsToSet[nNumArgs-1].Name = aDescr[nInd].Name;
161 aPropsToSet[nNumArgs-1].Value = aDescr[nInd].Value;
162 break;
163 }
164 else
165 OSL_ENSURE( sal_False, "Unacceptable property, will be ignored!\n" );
166 }
167 }
168 else
169 {
170 OSL_ENSURE( sal_False, "Wrong third argument!\n" );
171 throw uno::Exception(); // TODO: Illegal argument
172 }
173 }
174
175 // allow to use other ucp's
176 // if ( !isLocalNotFile_Impl( aURL ) )
177 if ( aURL.equalsIgnoreAsciiCaseAsciiL( "vnd.sun.star.pkg", 16 )
178 || aURL.equalsIgnoreAsciiCaseAsciiL( "vnd.sun.star.zip", 16 )
179 || ::utl::UCBContentHelper::IsDocument( aURL ) )
180 {
181 OSL_ENSURE( sal_False, "File system storages can be based only on file URLs!\n" ); // ???
182 throw uno::Exception(); // TODO: illegal argument
183 }
184
185 if ( ( nStorageMode & embed::ElementModes::WRITE ) && !( nStorageMode & embed::ElementModes::NOCREATE ) )
186 FSStorage::MakeFolderNoUI( aURL, sal_False );
187 else if ( !::utl::UCBContentHelper::IsFolder( aURL ) )
188 throw io::IOException(); // there is no such folder
189
190 ::ucbhelper::Content aResultContent(
191 aURL, uno::Reference< ucb::XCommandEnvironment >() );
192
193 // create storage based on source
194 return uno::Reference< uno::XInterface >(
195 static_cast< OWeakObject* >( new FSStorage( aResultContent,
196 nStorageMode,
197 aPropsToSet,
198 m_xFactory ) ),
199 uno::UNO_QUERY );
200 }
201
202 //-------------------------------------------------------------------------
getImplementationName()203 ::rtl::OUString SAL_CALL FSStorageFactory::getImplementationName()
204 throw ( uno::RuntimeException )
205 {
206 return impl_staticGetImplementationName();
207 }
208
209 //-------------------------------------------------------------------------
supportsService(const::rtl::OUString & ServiceName)210 sal_Bool SAL_CALL FSStorageFactory::supportsService( const ::rtl::OUString& ServiceName )
211 throw ( uno::RuntimeException )
212 {
213 uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
214
215 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
216 if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
217 return sal_True;
218
219 return sal_False;
220 }
221
222 //-------------------------------------------------------------------------
getSupportedServiceNames()223 uno::Sequence< ::rtl::OUString > SAL_CALL FSStorageFactory::getSupportedServiceNames()
224 throw ( uno::RuntimeException )
225 {
226 return impl_staticGetSupportedServiceNames();
227 }
228
229 //-------------------------------------------------------------------------
230
231 extern "C"
232 {
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)233 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment (
234 const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */)
235 {
236 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
237 }
238
component_getFactory(const sal_Char * pImplementationName,void * pServiceManager,void *)239 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
240 const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */)
241 {
242 void * pResult = 0;
243 if (pServiceManager)
244 {
245 uno::Reference< lang::XSingleServiceFactory > xFactory;
246 if (FSStorageFactory::impl_staticGetImplementationName().compareToAscii (pImplementationName) == 0)
247 {
248 xFactory = cppu::createOneInstanceFactory (
249 reinterpret_cast< lang::XMultiServiceFactory* >(pServiceManager),
250 FSStorageFactory::impl_staticGetImplementationName(),
251 FSStorageFactory::impl_staticCreateSelfInstance,
252 FSStorageFactory::impl_staticGetSupportedServiceNames() );
253 }
254 if (xFactory.is())
255 {
256 xFactory->acquire();
257 pResult = xFactory.get();
258 }
259 }
260 return pResult;
261 }
262
263 } // extern "C"
264
265