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