merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / localbe / localfilelayer.cxx
blobf3470c5f77d24bc0c8f0517f2df328d6995e0a8a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: localfilelayer.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
33 #include "localfilelayer.hxx"
34 #include "localoutputstream.hxx"
35 #include "oslstream.hxx"
36 #include <rtl/ustrbuf.hxx>
37 #include <com/sun/star/io/XActiveDataSource.hpp>
38 #include <com/sun/star/io/XActiveDataSink.hpp>
39 #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
42 namespace configmgr { namespace localbe {
44 //==============================================================================
46 //------------------------------------------------------------------------------
48 BasicLocalFileLayer::BasicLocalFileLayer(
49 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
50 const rtl::OUString& aComponentFile)
51 : mFactory(xFactory)
52 , mFileUrl(aComponentFile)
54 static const rtl::OUString kXMLLayerParser(RTL_CONSTASCII_USTRINGPARAM(
55 "com.sun.star.configuration.backend.xml.LayerParser")) ;
57 mLayerReader = uno::Reference<backend::XLayer>::query(
58 mFactory->createInstance(kXMLLayerParser)) ;
61 //------------------------------------------------------------------------------
63 SimpleLocalFileLayer::SimpleLocalFileLayer(
64 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
65 const rtl::OUString& aComponentFile)
66 : BasicLocalFileLayer(xFactory,aComponentFile)
69 //------------------------------------------------------------------------------
71 SimpleLocalFileLayer::SimpleLocalFileLayer(
72 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
73 const rtl::OUString& aBaseDir,
74 const rtl::OUString& aComponent)
75 : BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
78 //------------------------------------------------------------------------------
80 FlatLocalFileLayer::FlatLocalFileLayer(
81 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
82 const rtl::OUString& aBaseDir,
83 const rtl::OUString& aComponent)
84 : BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
85 , mLayerWriter( createLayerWriter() )
88 //------------------------------------------------------------------------------
90 BasicCompositeLocalFileLayer::BasicCompositeLocalFileLayer(
91 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
92 const rtl::OUString& aComponentFile)
93 : BasicLocalFileLayer(xFactory,aComponentFile)
96 //------------------------------------------------------------------------------
98 CompositeLocalFileLayer::CompositeLocalFileLayer(
99 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
100 const rtl::OUString& aComponent,
101 const std::vector<rtl::OUString>& aSublayerDirectories)
102 : BasicCompositeLocalFileLayer(xFactory,rtl::OUString())
104 fillSubLayerLists(aSublayerDirectories, aComponent) ;
106 //------------------------------------------------------------------------------
108 FullCompositeLocalFileLayer::FullCompositeLocalFileLayer(
109 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
110 const rtl::OUString& aBaseDir,
111 const rtl::OUString& aComponent,
112 const std::vector<rtl::OUString>& aSublayerDirectories)
113 : BasicCompositeLocalFileLayer(xFactory,aBaseDir + aComponent)
114 , mLayerWriter( createLayerWriter() )
116 fillSubLayerLists(aSublayerDirectories, aComponent) ;
118 //------------------------------------------------------------------------------
120 BasicLocalFileLayer::~BasicLocalFileLayer() {}
121 //------------------------------------------------------------------------------
123 SimpleLocalFileLayer::~SimpleLocalFileLayer() {}
124 //------------------------------------------------------------------------------
126 FlatLocalFileLayer::~FlatLocalFileLayer() {}
127 //------------------------------------------------------------------------------
129 CompositeLocalFileLayer::~CompositeLocalFileLayer() {}
130 //------------------------------------------------------------------------------
132 FullCompositeLocalFileLayer::~FullCompositeLocalFileLayer() {}
133 //------------------------------------------------------------------------------
135 uno::Reference<backend::XLayerHandler> BasicLocalFileLayer::createLayerWriter()
137 static const rtl::OUString kXMLLayerWriter(RTL_CONSTASCII_USTRINGPARAM(
138 "com.sun.star.configuration.backend.xml.LayerWriter")) ;
140 uno::Reference< uno::XInterface > xWriter = mFactory->createInstance(kXMLLayerWriter);
142 return uno::Reference<backend::XLayerHandler>(xWriter,uno::UNO_REF_QUERY_THROW) ;
144 //------------------------------------------------------------------------------
146 static inline void readEmptyLayer(const uno::Reference<backend::XLayerHandler>& xHandler)
148 OSL_ASSERT(xHandler.is());
149 xHandler->startLayer();
150 xHandler->endLayer();
152 //------------------------------------------------------------------------------
154 void BasicLocalFileLayer::readData(
155 backend::XLayer * pContext,
156 const uno::Reference<backend::XLayerHandler>& xHandler,
157 const rtl::OUString& aFileUrl)
158 throw ( backend::MalformedDataException,
159 lang::NullPointerException,
160 lang::WrappedTargetException,
161 uno::RuntimeException)
163 if (!xHandler.is())
165 rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
166 "LocalFileLayer - Cannot readData: Handler is NULL."));
168 throw lang::NullPointerException(sMessage,pContext);
171 osl::File blobFile(aFileUrl) ;
172 osl::File::RC errorCode = blobFile.open(OpenFlag_Read) ;
174 switch (errorCode)
176 case osl::File::E_None: // got it
178 uno::Reference<io::XActiveDataSink> xAS(mLayerReader, uno::UNO_QUERY_THROW);
180 uno::Reference<io::XInputStream> xStream( new OSLInputStreamWrapper(blobFile) );
182 xAS->setInputStream(xStream);
184 mLayerReader->readData(xHandler) ;
186 break;
188 case osl::File::E_NOENT: // no layer => empty layer
189 readEmptyLayer(xHandler);
190 break;
192 default:
194 rtl::OUStringBuffer sMsg;
195 sMsg.appendAscii("LocalFile Layer: Cannot open input file \"");
196 sMsg.append(aFileUrl);
197 sMsg.appendAscii("\" : ");
198 sMsg.append(FileHelper::createOSLErrorString(errorCode));
200 io::IOException ioe(sMsg.makeStringAndClear(),pContext);
202 sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(ioe.Message);
203 throw backend::BackendAccessException(sMsg.makeStringAndClear(),pContext,uno::makeAny(ioe));
207 //------------------------------------------------------------------------------
209 void SAL_CALL SimpleLocalFileLayer::readData(
210 const uno::Reference<backend::XLayerHandler>& xHandler)
211 throw ( backend::MalformedDataException,
212 lang::NullPointerException,
213 lang::WrappedTargetException,
214 uno::RuntimeException)
216 BasicLocalFileLayer::readData(this,xHandler, getFileUrl()) ;
218 //------------------------------------------------------------------------------
220 void SAL_CALL FlatLocalFileLayer::readData(
221 const uno::Reference<backend::XLayerHandler>& xHandler)
222 throw ( backend::MalformedDataException,
223 lang::NullPointerException,
224 lang::WrappedTargetException,
225 uno::RuntimeException)
227 BasicLocalFileLayer::readData(this,xHandler, getFileUrl() ) ;
229 //------------------------------------------------------------------------------
231 void SAL_CALL CompositeLocalFileLayer::readData(
232 const uno::Reference<backend::XLayerHandler>& xHandler)
233 throw ( backend::MalformedDataException,
234 lang::NullPointerException,
235 lang::WrappedTargetException,
236 uno::RuntimeException)
238 if (!xHandler.is())
240 rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
241 "LocalFileLayer - Cannot readData: Handler is NULL."));
243 throw lang::NullPointerException(sMessage,*this);
246 readEmptyLayer(xHandler) ;
248 //------------------------------------------------------------------------------
250 void SAL_CALL FullCompositeLocalFileLayer::readData(
251 const uno::Reference<backend::XLayerHandler>& xHandler)
252 throw ( backend::MalformedDataException,
253 lang::NullPointerException,
254 lang::WrappedTargetException,
255 uno::RuntimeException)
257 BasicLocalFileLayer::readData(static_cast<backend::XCompositeLayer*>(this),xHandler, getFileUrl() ) ;
259 //------------------------------------------------------------------------------
261 void SAL_CALL BasicCompositeLocalFileLayer::readSubLayerData(
262 backend::XCompositeLayer * pContext,
263 const uno::Reference<backend::XLayerHandler>& xHandler,
264 const rtl::OUString& aSubLayerId)
265 throw ( backend::MalformedDataException,
266 lang::IllegalArgumentException,
267 lang::NullPointerException,
268 lang::WrappedTargetException,
269 uno::RuntimeException)
271 if (!xHandler.is())
273 rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
274 "CompositeLocalFileLayer - Cannot readSubLayerData: Handler is NULL."));
276 throw lang::NullPointerException(sMessage,pContext);
279 sal_Int32 i ;
281 for (i = 0 ; i < mSubLayers.getLength() ; ++ i) {
282 if (mSubLayers [i].equals(aSubLayerId)) { break ; }
284 if (i == mSubLayers.getLength())
286 rtl::OUStringBuffer message ;
288 message.appendAscii("Sublayer Id '").append(aSubLayerId) ;
289 message.appendAscii("' is unknown") ;
290 throw lang::IllegalArgumentException(message.makeStringAndClear(),
291 pContext, 2) ;
293 if (mSubLayerFiles[i].getLength() != 0)
294 BasicLocalFileLayer::readData(pContext,xHandler, mSubLayerFiles [i]) ;
295 else
296 readEmptyLayer(xHandler);
298 //------------------------------------------------------------------------------
300 void SAL_CALL CompositeLocalFileLayer::readSubLayerData(
301 const uno::Reference<backend::XLayerHandler>& xHandler,
302 const rtl::OUString& aSubLayerId)
303 throw ( backend::MalformedDataException,
304 lang::IllegalArgumentException,
305 lang::NullPointerException,
306 lang::WrappedTargetException,
307 uno::RuntimeException)
309 return BasicCompositeLocalFileLayer::readSubLayerData(this,xHandler,aSubLayerId);
311 //------------------------------------------------------------------------------
313 void SAL_CALL FullCompositeLocalFileLayer::readSubLayerData(
314 const uno::Reference<backend::XLayerHandler>& xHandler,
315 const rtl::OUString& aSubLayerId)
316 throw ( backend::MalformedDataException,
317 lang::IllegalArgumentException,
318 lang::NullPointerException,
319 lang::WrappedTargetException,
320 uno::RuntimeException)
322 return BasicCompositeLocalFileLayer::readSubLayerData(this,xHandler,aSubLayerId);
324 //------------------------------------------------------------------------------
326 void SAL_CALL FlatLocalFileLayer::replaceWith(
327 const uno::Reference<backend::XLayer>& aNewLayer)
328 throw ( backend::MalformedDataException,
329 lang::NullPointerException,
330 lang::WrappedTargetException,
331 uno::RuntimeException)
333 if (!aNewLayer.is())
335 rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
336 "LocalFileLayer - Cannot replaceWith: Replacement layer is NULL."));
338 throw lang::NullPointerException(sMessage,*this);
340 OSL_ENSURE( !uno::Reference<backend::XCompositeLayer>::query(aNewLayer).is(),
341 "Warning: correct updates with composite layers are not implemented");
343 uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY_THROW);
345 LocalOutputStream * pStream = new LocalOutputStream(getFileUrl());
346 uno::Reference<io::XOutputStream> xStream( pStream );
348 xAS->setOutputStream(xStream);
350 aNewLayer->readData(mLayerWriter) ;
352 pStream->finishOutput();
354 // clear the output stream
355 xStream.clear();
356 xAS->setOutputStream(xStream);
358 //------------------------------------------------------------------------------
360 void SAL_CALL FullCompositeLocalFileLayer::replaceWith(
361 const uno::Reference<backend::XLayer>& aNewLayer)
362 throw (backend::MalformedDataException, lang::NullPointerException,
363 lang::WrappedTargetException, uno::RuntimeException)
365 if (!aNewLayer.is())
367 rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
368 "LocalFileLayer - Cannot replaceWith: Replacement layer is NULL."));
370 throw lang::NullPointerException(sMessage,*this);
372 OSL_ENSURE( !uno::Reference<backend::XCompositeLayer>::query(aNewLayer).is(),
373 "Warning: correct updates with composite layers are not implemented");
375 uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY_THROW);
377 LocalOutputStream * pStream = new LocalOutputStream(getFileUrl());
378 uno::Reference<io::XOutputStream> xStream( pStream );
380 xAS->setOutputStream(xStream);
382 aNewLayer->readData(mLayerWriter) ;
384 pStream->finishOutput();
386 // clear the output stream
387 xStream.clear();
388 xAS->setOutputStream(xStream);
390 //------------------------------------------------------------------------------
392 rtl::OUString BasicLocalFileLayer::getTimestamp(const rtl::OUString& aFileUrl)
394 TimeValue timevalue = {0,0};
395 sal_uInt64 aSize = FileHelper::getModifyStatus(aFileUrl,timevalue) ;
396 oslDateTime fileStamp ;
397 rtl::OUString retCode ;
399 if (osl_getDateTimeFromTimeValue(&timevalue, &fileStamp))
401 // truncate to 32 bits
402 unsigned long aLongSize = static_cast<sal_Int32>(aSize);
404 sal_Char asciiStamp [50] ;
406 sprintf(asciiStamp, "%04u%02u%02u%02u%02u%02uZ%010lu",
407 unsigned(fileStamp.Year), unsigned(fileStamp.Month), unsigned(fileStamp.Day),
408 unsigned(fileStamp.Hours), unsigned(fileStamp.Minutes), unsigned(fileStamp.Seconds),
409 aLongSize) ;
410 retCode = rtl::OUString::createFromAscii(asciiStamp) ;
412 return retCode ;
414 //------------------------------------------------------------------------------
416 rtl::OUString SimpleLocalFileLayer::getTimestamp()
417 throw (uno::RuntimeException)
419 rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
421 return sStamp;
423 //------------------------------------------------------------------------------
425 rtl::OUString FlatLocalFileLayer::getTimestamp()
426 throw (uno::RuntimeException)
428 rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
430 return sStamp;
432 //------------------------------------------------------------------------------
434 rtl::OUString FullCompositeLocalFileLayer::getTimestamp()
435 throw (uno::RuntimeException)
437 rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
438 #if 0 // thus far composite layers are only manipulated via the main layer
439 for (std::vector<rtl::OUString>::const_iterator it = mSubLayerFiles.begin();
440 it != mSubLayerFiles.end();
441 ++it)
443 rtl::OUString sSublayerTime = BasicLocalFileLayer::getTimestamp(*it);
444 if (sStamp < sSublayerTime)
445 sStamp = sSublayerTime;
447 #endif
448 return sStamp;
450 //------------------------------------------------------------------------------
452 void BasicCompositeLocalFileLayer::fillSubLayerLists( const std::vector<rtl::OUString>& aSublayerDirectories,
453 const rtl::OUString& aComponent)
455 std::vector<rtl::OUString>::size_type const nSublayerCount = aSublayerDirectories.size();
456 mSubLayers.realloc(nSublayerCount);
457 mSubLayerFiles.resize(nSublayerCount);
459 for (std::vector<rtl::OUString>::size_type i = 0; i < nSublayerCount; ++i)
461 mSubLayers[i] = FileHelper::getFileName(aSublayerDirectories[i]);
463 // Let's check whether the sublayer exists for the
464 // particular component.
465 rtl::OUString subLayerFile(aSublayerDirectories[i] + aComponent) ;
466 if (FileHelper::fileExists(subLayerFile))
468 mSubLayerFiles[i] = subLayerFile;
470 else
471 OSL_ASSERT(mSubLayerFiles[i].getLength() == 0);
474 //------------------------------------------------------------------------------
476 static bool findSubLayers(const rtl::OUString& aResDir,
477 std::vector<rtl::OUString>& aSublayerDirectories)
479 if (aResDir.getLength() == 0) return false;
481 // Extract the directory where the file is located
482 osl::Directory directory(aResDir) ;
483 if (directory.open() != osl::Directory::E_None) return false;
485 osl::DirectoryItem item ;
486 osl::FileStatus status(osl_FileStatus_Mask_Type |
487 osl_FileStatus_Mask_FileURL) ;
489 while (directory.getNextItem(item) == osl::Directory::E_None)
491 if (item.getFileStatus(status) == osl::Directory::E_None)
493 if (status.getFileType() == osl::FileStatus::Directory)
495 aSublayerDirectories.push_back(status.getFileURL()) ;
499 return !aSublayerDirectories.empty();
501 //------------------------------------------------------------------------------
503 uno::Reference<backend::XLayer> createReadonlyLocalFileLayer(
504 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
505 const rtl::OUString& aBaseDir,
506 const rtl::OUString& aComponent,
507 const rtl::OUString& aResDir)
509 uno::Reference<backend::XLayer> xResult;
511 std::vector<rtl::OUString> aSublayers;
512 if (aBaseDir.getLength() == 0)
514 findSubLayers(aResDir,aSublayers);
515 xResult.set( new CompositeLocalFileLayer(xFactory,aComponent,aSublayers) );
517 else if (findSubLayers(aResDir,aSublayers))
519 // there is no readonly full composite layer - take the updatable one
520 backend::XCompositeLayer * pNewLayer =
521 new FullCompositeLocalFileLayer(xFactory,aBaseDir,aComponent,aSublayers);
522 xResult.set( pNewLayer );
524 else
526 xResult.set( new SimpleLocalFileLayer(xFactory,aBaseDir,aComponent) );
528 return xResult;
530 //------------------------------------------------------------------------------
532 uno::Reference<backend::XUpdatableLayer> createUpdatableLocalFileLayer(
533 const uno::Reference<lang::XMultiServiceFactory>& xFactory,
534 const rtl::OUString& aBaseDir,
535 const rtl::OUString& aComponent,
536 const rtl::OUString& aResDir)
538 uno::Reference<backend::XUpdatableLayer> xResult;
540 std::vector<rtl::OUString> aSublayers;
541 if (findSubLayers(aResDir,aSublayers))
543 xResult.set( new FullCompositeLocalFileLayer(xFactory,aBaseDir,aComponent,aSublayers) );
545 else if (aBaseDir.getLength() != 0)
547 xResult.set( new FlatLocalFileLayer(xFactory,aBaseDir,aComponent) );
549 else
550 OSL_ENSURE(false,"WARNING: Trying to create an updatable ressource-only layer");
552 return xResult;
554 //------------------------------------------------------------------------------
555 //------------------------------------------------------------------------------
557 enum
559 LAYER_PROPERTY_URL = 1
562 #define PROPNAME( name ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( name ) )
563 #define PROPTYPE( type ) getCppuType( static_cast< type const *>( 0 ) )
565 // cppu::OPropertySetHelper
566 cppu::IPropertyArrayHelper * SAL_CALL LayerPropertyHelper::newInfoHelper()
568 com::sun::star::beans::Property properties[] =
570 com::sun::star::beans::Property(PROPNAME("URL"), LAYER_PROPERTY_URL, PROPTYPE(rtl::OUString), com::sun::star::beans::PropertyAttribute::READONLY)
573 return new cppu::OPropertyArrayHelper(properties, sizeof(properties)/sizeof(properties[0]));
576 #define MESSAGE( text ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Layer Properties: " text ) )
578 void SAL_CALL LayerPropertyHelper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& /*rValue*/ )
579 throw (uno::Exception)
581 namespace beans = com::sun::star::beans;
583 switch (nHandle)
585 case LAYER_PROPERTY_URL:
586 OSL_ENSURE(false, "Error: trying to set a READONLY property");
587 throw beans::PropertyVetoException(MESSAGE("Property 'URL' is read-only"),*this);
589 default:
590 OSL_ENSURE(false, "Error: trying to set an UNKNOWN property");
591 throw beans::UnknownPropertyException(MESSAGE("Trying to set an unknown property"),*this);
595 void SAL_CALL LayerPropertyHelper::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const
597 switch (nHandle)
599 case LAYER_PROPERTY_URL:
600 rValue = uno::makeAny( this->getLayerUrl() );
601 break;
603 default:
604 OSL_ENSURE(false, "Error: trying to get an UNKNOWN property");
605 break;
609 //------------------------------------------------------------------------------
610 } } // configmgr.localbe