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_comphelper.hxx"
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/container/XContainerQuery.hpp>
32 #include <com/sun/star/document/XTypeDetection.hpp>
34 #include <comphelper/fileformat.h>
35 #include <comphelper/mimeconfighelper.hxx>
36 #include <comphelper/classids.hxx>
37 #include <comphelper/sequenceashashmap.hxx>
38 #include <comphelper/documentconstants.hxx>
41 using namespace ::com::sun::star
;
42 using namespace comphelper
;
44 //-----------------------------------------------------------------------
45 MimeConfigurationHelper::MimeConfigurationHelper( const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
46 : m_xFactory( xFactory
)
48 if ( !m_xFactory
.is() )
49 throw uno::RuntimeException();
52 //-----------------------------------------------------------------------
53 ::rtl::OUString
MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence
< sal_Int8
>& aClassID
)
55 ::rtl::OUString aResult
;
57 if ( aClassID
.getLength() == 16 )
59 for ( sal_Int32 nInd
= 0; nInd
< aClassID
.getLength(); nInd
++ )
61 if ( nInd
== 4 || nInd
== 6 || nInd
== 8 || nInd
== 10 )
62 aResult
+= ::rtl::OUString::createFromAscii( "-" );
64 sal_Int32 nDigit1
= (sal_Int32
)( (sal_uInt8
)aClassID
[nInd
] / 16 );
65 sal_Int32 nDigit2
= (sal_uInt8
)aClassID
[nInd
] % 16;
66 aResult
+= ::rtl::OUString::valueOf( nDigit1
, 16 );
67 aResult
+= ::rtl::OUString::valueOf( nDigit2
, 16 );
74 //-----------------------------------------------------------------------
75 sal_uInt8
GetDigit_Impl( sal_Char aChar
)
77 if ( aChar
>= '0' && aChar
<= '9' )
79 else if ( aChar
>= 'a' && aChar
<= 'f' )
80 return aChar
- 'a' + 10;
81 else if ( aChar
>= 'A' && aChar
<= 'F' )
82 return aChar
- 'A' + 10;
87 //-----------------------------------------------------------------------
88 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassIDRepresentation( const ::rtl::OUString
& aClassID
)
90 sal_Int32 nLength
= aClassID
.getLength();
93 ::rtl::OString aCharClassID
= ::rtl::OUStringToOString( aClassID
, RTL_TEXTENCODING_ASCII_US
);
94 const sal_Char
* pString
= aCharClassID
.getStr();
97 uno::Sequence
< sal_Int8
> aResult( 16 );
99 sal_Int32 nStrPointer
= 0;
100 sal_Int32 nSeqInd
= 0;
101 while( nSeqInd
< 16 && nStrPointer
+ 1 < nLength
)
103 sal_uInt8 nDigit1
= GetDigit_Impl( pString
[nStrPointer
++] );
104 sal_uInt8 nDigit2
= GetDigit_Impl( pString
[nStrPointer
++] );
106 if ( nDigit1
> 15 || nDigit2
> 15 )
109 aResult
[nSeqInd
++] = (sal_Int8
)( nDigit1
* 16 + nDigit2
);
111 if ( nStrPointer
< nLength
&& pString
[nStrPointer
] == '-' )
115 if ( nSeqInd
== 16 && nStrPointer
== nLength
)
120 return uno::Sequence
< sal_Int8
>();
123 //-----------------------------------------------------------------------
124 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetConfigurationByPath( const ::rtl::OUString
& aPath
)
126 osl::MutexGuard
aGuard( m_aMutex
);
128 uno::Reference
< container::XNameAccess
> xConfig
;
132 if ( !m_xConfigProvider
.is() )
133 m_xConfigProvider
= uno::Reference
< lang::XMultiServiceFactory
>(
134 m_xFactory
->createInstance(
135 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
136 uno::UNO_QUERY_THROW
);
138 uno::Sequence
< uno::Any
> aArgs( 1 );
139 beans::PropertyValue aPathProp
;
140 aPathProp
.Name
= ::rtl::OUString::createFromAscii( "nodepath" );
141 aPathProp
.Value
<<= aPath
;
142 aArgs
[0] <<= aPathProp
;
144 xConfig
= uno::Reference
< container::XNameAccess
>(
145 m_xConfigProvider
->createInstanceWithArguments(
146 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
150 catch( uno::Exception
& )
156 //-----------------------------------------------------------------------
157 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetObjConfiguration()
159 osl::MutexGuard
aGuard( m_aMutex
);
161 if ( !m_xObjectConfig
.is() )
162 m_xObjectConfig
= GetConfigurationByPath(
163 ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Embedding/Objects" ) );
165 return m_xObjectConfig
;
168 //-----------------------------------------------------------------------
169 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetVerbsConfiguration()
171 osl::MutexGuard
aGuard( m_aMutex
);
173 if ( !m_xVerbsConfig
.is() )
174 m_xVerbsConfig
= GetConfigurationByPath(
175 ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Embedding/Verbs" ) );
177 return m_xVerbsConfig
;
180 //-----------------------------------------------------------------------
181 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetMediaTypeConfiguration()
183 osl::MutexGuard
aGuard( m_aMutex
);
185 if ( !m_xMediaTypeConfig
.is() )
186 m_xMediaTypeConfig
= GetConfigurationByPath(
187 ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations" ) );
189 return m_xMediaTypeConfig
;
192 //-----------------------------------------------------------------------
193 uno::Reference
< container::XNameAccess
> MimeConfigurationHelper::GetFilterFactory()
195 osl::MutexGuard
aGuard( m_aMutex
);
197 if ( !m_xFilterFactory
.is() )
198 m_xFilterFactory
.set(
199 m_xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
202 return m_xFilterFactory
;
205 //-----------------------------------------------------------------------
206 sal_Int32
MimeConfigurationHelper::GetFilterFlags( const ::rtl::OUString
& aFilterName
)
208 sal_Int32 nFlags
= 0;
211 if ( aFilterName
.getLength() )
213 uno::Reference
< container::XNameAccess
> xFilterFactory(
215 uno::UNO_SET_THROW
);
217 uno::Any aFilterAny
= xFilterFactory
->getByName( aFilterName
);
218 uno::Sequence
< beans::PropertyValue
> aData
;
219 if ( aFilterAny
>>= aData
)
221 SequenceAsHashMap
aFilterHM( aData
);
222 nFlags
= aFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ), (sal_Int32
)0 );
225 } catch( uno::Exception
& )
231 //-------------------------------------------------------------------------
232 ::rtl::OUString
MimeConfigurationHelper::GetDocServiceNameFromFilter( const ::rtl::OUString
& aFilterName
)
234 ::rtl::OUString aDocServiceName
;
238 uno::Reference
< container::XNameAccess
> xFilterFactory(
240 uno::UNO_SET_THROW
);
242 uno::Any aFilterAnyData
= xFilterFactory
->getByName( aFilterName
);
243 uno::Sequence
< beans::PropertyValue
> aFilterData
;
244 if ( aFilterAnyData
>>= aFilterData
)
246 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
247 if ( aFilterData
[nInd
].Name
.equalsAscii( "DocumentService" ) )
248 aFilterData
[nInd
].Value
>>= aDocServiceName
;
251 catch( uno::Exception
& )
254 return aDocServiceName
;
257 //-------------------------------------------------------------------------
258 ::rtl::OUString
MimeConfigurationHelper::GetDocServiceNameFromMediaType( const ::rtl::OUString
& aMediaType
)
260 uno::Reference
< container::XContainerQuery
> xTypeCFG(
261 m_xFactory
->createInstance(
262 ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
269 // make query for all types matching the properties
270 uno::Sequence
< beans::NamedValue
> aSeq( 1 );
271 aSeq
[0].Name
= ::rtl::OUString::createFromAscii( "MediaType" );
272 aSeq
[0].Value
<<= aMediaType
;
274 uno::Reference
< container::XEnumeration
> xEnum
= xTypeCFG
->createSubSetEnumerationByProperties( aSeq
);
275 while ( xEnum
->hasMoreElements() )
277 uno::Sequence
< beans::PropertyValue
> aType
;
278 if ( xEnum
->nextElement() >>= aType
)
280 for ( sal_Int32 nInd
= 0; nInd
< aType
.getLength(); nInd
++ )
282 ::rtl::OUString aFilterName
;
283 if ( aType
[nInd
].Name
.equalsAscii( "PreferredFilter" )
284 && ( aType
[nInd
].Value
>>= aFilterName
) && aFilterName
.getLength() )
286 ::rtl::OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
287 if ( aDocumentName
.getLength() )
288 return aDocumentName
;
294 catch( uno::Exception
& )
298 return ::rtl::OUString();
301 //-------------------------------------------------------------------------
302 sal_Bool
MimeConfigurationHelper::GetVerbByShortcut( const ::rtl::OUString
& aVerbShortcut
,
303 embed::VerbDescriptor
& aDescriptor
)
305 sal_Bool bResult
= sal_False
;
307 uno::Reference
< container::XNameAccess
> xVerbsConfig
= GetVerbsConfiguration();
308 uno::Reference
< container::XNameAccess
> xVerbsProps
;
311 if ( xVerbsConfig
.is() && ( xVerbsConfig
->getByName( aVerbShortcut
) >>= xVerbsProps
) && xVerbsProps
.is() )
313 embed::VerbDescriptor aTempDescr
;
314 if ( ( xVerbsProps
->getByName( ::rtl::OUString::createFromAscii( "VerbID" ) ) >>= aTempDescr
.VerbID
)
315 && ( xVerbsProps
->getByName( ::rtl::OUString::createFromAscii( "VerbUIName" ) ) >>= aTempDescr
.VerbName
)
316 && ( xVerbsProps
->getByName( ::rtl::OUString::createFromAscii( "VerbFlags" ) ) >>= aTempDescr
.VerbFlags
)
317 && ( xVerbsProps
->getByName( ::rtl::OUString::createFromAscii( "VerbAttributes" ) ) >>= aTempDescr
.VerbAttributes
) )
319 aDescriptor
= aTempDescr
;
324 catch( uno::Exception
& )
331 //-------------------------------------------------------------------------
332 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjPropsFromConfigEntry(
333 const uno::Sequence
< sal_Int8
>& aClassID
,
334 const uno::Reference
< container::XNameAccess
>& xObjectProps
)
336 uno::Sequence
< beans::NamedValue
> aResult
;
338 if ( aClassID
.getLength() == 16 )
342 uno::Sequence
< ::rtl::OUString
> aObjPropNames
= xObjectProps
->getElementNames();
344 aResult
.realloc( aObjPropNames
.getLength() + 1 );
345 aResult
[0].Name
= ::rtl::OUString::createFromAscii( "ClassID" );
346 aResult
[0].Value
<<= aClassID
;
348 for ( sal_Int32 nInd
= 0; nInd
< aObjPropNames
.getLength(); nInd
++ )
350 aResult
[nInd
+ 1].Name
= aObjPropNames
[nInd
];
352 if ( aObjPropNames
[nInd
].equalsAscii( "ObjectVerbs" ) )
354 uno::Sequence
< ::rtl::OUString
> aVerbShortcuts
;
355 if ( xObjectProps
->getByName( aObjPropNames
[nInd
] ) >>= aVerbShortcuts
)
357 uno::Sequence
< embed::VerbDescriptor
> aVerbDescriptors( aVerbShortcuts
.getLength() );
358 for ( sal_Int32 nVerbI
= 0; nVerbI
< aVerbShortcuts
.getLength(); nVerbI
++ )
359 if ( !GetVerbByShortcut( aVerbShortcuts
[nVerbI
], aVerbDescriptors
[nVerbI
] ) )
360 throw uno::RuntimeException();
362 aResult
[nInd
+1].Value
<<= aVerbDescriptors
;
365 throw uno::RuntimeException();
368 aResult
[nInd
+1].Value
= xObjectProps
->getByName( aObjPropNames
[nInd
] );
371 catch( uno::Exception
& )
373 aResult
.realloc( 0 );
380 //-----------------------------------------------------------------------
381 ::rtl::OUString
MimeConfigurationHelper::GetExplicitlyRegisteredObjClassID( const ::rtl::OUString
& aMediaType
)
383 ::rtl::OUString aStringClassID
;
385 uno::Reference
< container::XNameAccess
> xMediaTypeConfig
= GetMediaTypeConfiguration();
388 if ( xMediaTypeConfig
.is() )
389 xMediaTypeConfig
->getByName( aMediaType
) >>= aStringClassID
;
391 catch( uno::Exception
& )
395 return aStringClassID
;
399 //-----------------------------------------------------------------------
400 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByStringClassID(
401 const ::rtl::OUString
& aStringClassID
)
403 uno::Sequence
< beans::NamedValue
> aObjProps
;
405 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
406 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
408 aObjProps
.realloc(2);
409 aObjProps
[0].Name
= ::rtl::OUString::createFromAscii("ObjectFactory");
410 aObjProps
[0].Value
<<= ::rtl::OUString::createFromAscii("com.sun.star.embed.OOoSpecialEmbeddedObjectFactory");
411 aObjProps
[1].Name
= ::rtl::OUString::createFromAscii("ClassID");
412 aObjProps
[1].Value
<<= aClassID
;
416 if ( aClassID
.getLength() == 16 )
418 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
419 uno::Reference
< container::XNameAccess
> xObjectProps
;
422 // TODO/LATER: allow to provide ClassID string in any format, only digits are counted
423 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
424 aObjProps
= GetObjPropsFromConfigEntry( aClassID
, xObjectProps
);
426 catch( uno::Exception
& )
434 //-----------------------------------------------------------------------
435 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByClassID(
436 const uno::Sequence
< sal_Int8
>& aClassID
)
438 uno::Sequence
< beans::NamedValue
> aObjProps
;
439 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
441 aObjProps
.realloc(2);
442 aObjProps
[0].Name
= ::rtl::OUString::createFromAscii("ObjectFactory");
443 aObjProps
[0].Value
<<= ::rtl::OUString::createFromAscii("com.sun.star.embed.OOoSpecialEmbeddedObjectFactory");
444 aObjProps
[1].Name
= ::rtl::OUString::createFromAscii("ClassID");
445 aObjProps
[1].Value
<<= aClassID
;
448 ::rtl::OUString aStringClassID
= GetStringClassIDRepresentation( aClassID
);
449 if ( aStringClassID
.getLength() )
451 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
452 uno::Reference
< container::XNameAccess
> xObjectProps
;
455 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
456 aObjProps
= GetObjPropsFromConfigEntry( aClassID
, xObjectProps
);
458 catch( uno::Exception
& )
466 //-----------------------------------------------------------------------
467 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByMediaType( const ::rtl::OUString
& aMediaType
)
469 uno::Sequence
< beans::NamedValue
> aObject
=
470 GetObjectPropsByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
471 if ( aObject
.getLength() )
474 ::rtl::OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
475 if ( aDocumentName
.getLength() )
476 return GetObjectPropsByDocumentName( aDocumentName
);
478 return uno::Sequence
< beans::NamedValue
>();
481 //-----------------------------------------------------------------------
482 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByFilter( const ::rtl::OUString
& aFilterName
)
484 ::rtl::OUString aDocumentName
= GetDocServiceNameFromFilter( aFilterName
);
485 if ( aDocumentName
.getLength() )
486 return GetObjectPropsByDocumentName( aDocumentName
);
488 return uno::Sequence
< beans::NamedValue
>();
491 //-----------------------------------------------------------------------
492 uno::Sequence
< beans::NamedValue
> MimeConfigurationHelper::GetObjectPropsByDocumentName( const ::rtl::OUString
& aDocName
)
494 if ( aDocName
.getLength() )
496 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
497 if ( xObjConfig
.is() )
501 uno::Sequence
< ::rtl::OUString
> aClassIDs
= xObjConfig
->getElementNames();
502 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
504 uno::Reference
< container::XNameAccess
> xObjectProps
;
505 ::rtl::OUString aEntryDocName
;
507 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
508 && ( xObjectProps
->getByName(
509 ::rtl::OUString::createFromAscii( "ObjectDocumentServiceName" ) ) >>= aEntryDocName
)
510 && aEntryDocName
.equals( aDocName
) )
512 return GetObjPropsFromConfigEntry( GetSequenceClassIDRepresentation( aClassIDs
[nInd
] ),
517 catch( uno::Exception
& )
522 return uno::Sequence
< beans::NamedValue
>();
525 //-----------------------------------------------------------------------
526 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByClassID( const uno::Sequence
< sal_Int8
>& aClassID
)
528 return GetFactoryNameByStringClassID( GetStringClassIDRepresentation( aClassID
) );
531 //-----------------------------------------------------------------------
532 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByStringClassID( const ::rtl::OUString
& aStringClassID
)
534 ::rtl::OUString aResult
;
536 if ( aStringClassID
.getLength() )
538 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
539 uno::Reference
< container::XNameAccess
> xObjectProps
;
542 if ( xObjConfig
.is() && ( xObjConfig
->getByName( aStringClassID
.toAsciiUpperCase() ) >>= xObjectProps
) && xObjectProps
.is() )
543 xObjectProps
->getByName( ::rtl::OUString::createFromAscii( "ObjectFactory" ) ) >>= aResult
;
545 catch( uno::Exception
& )
547 uno::Sequence
< sal_Int8
> aClassID
= GetSequenceClassIDRepresentation( aStringClassID
);
548 if ( ClassIDsEqual( aClassID
, GetSequenceClassID( SO3_DUMMY_CLASSID
) ) )
549 return ::rtl::OUString::createFromAscii("com.sun.star.embed.OOoSpecialEmbeddedObjectFactory");
556 //-----------------------------------------------------------------------
557 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByDocumentName( const ::rtl::OUString
& aDocName
)
559 ::rtl::OUString aResult
;
561 if ( aDocName
.getLength() )
563 uno::Reference
< container::XNameAccess
> xObjConfig
= GetObjConfiguration();
564 if ( xObjConfig
.is() )
568 uno::Sequence
< ::rtl::OUString
> aClassIDs
= xObjConfig
->getElementNames();
569 for ( sal_Int32 nInd
= 0; nInd
< aClassIDs
.getLength(); nInd
++ )
571 uno::Reference
< container::XNameAccess
> xObjectProps
;
572 ::rtl::OUString aEntryDocName
;
574 if ( ( xObjConfig
->getByName( aClassIDs
[nInd
] ) >>= xObjectProps
) && xObjectProps
.is()
575 && ( xObjectProps
->getByName(
576 ::rtl::OUString::createFromAscii( "ObjectDocumentServiceName" ) ) >>= aEntryDocName
)
577 && aEntryDocName
.equals( aDocName
) )
579 xObjectProps
->getByName( ::rtl::OUString::createFromAscii( "ObjectFactory" ) ) >>= aResult
;
584 catch( uno::Exception
& )
593 //-----------------------------------------------------------------------
594 ::rtl::OUString
MimeConfigurationHelper::GetFactoryNameByMediaType( const ::rtl::OUString
& aMediaType
)
596 ::rtl::OUString aResult
= GetFactoryNameByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType
) );
598 if ( !aResult
.getLength() )
600 ::rtl::OUString aDocumentName
= GetDocServiceNameFromMediaType( aMediaType
);
601 if ( aDocumentName
.getLength() )
602 aResult
= GetFactoryNameByDocumentName( aDocumentName
);
608 //-----------------------------------------------------------------------
609 ::rtl::OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
610 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
611 sal_Bool bIgnoreType
)
613 ::rtl::OUString aFilterName
;
615 for ( sal_Int32 nInd
= 0; nInd
< aMediaDescr
.getLength(); nInd
++ )
616 if ( aMediaDescr
[nInd
].Name
.equalsAscii( "FilterName" ) )
617 aMediaDescr
[nInd
].Value
>>= aFilterName
;
619 if ( !aFilterName
.getLength() )
621 // filter name is not specified, so type detection should be done
623 uno::Reference
< document::XTypeDetection
> xTypeDetection(
624 m_xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
627 if ( !xTypeDetection
.is() )
628 throw uno::RuntimeException(); // TODO
630 // typedetection can change the mode, add a stream and so on, thus a copy should be used
631 uno::Sequence
< beans::PropertyValue
> aTempMD( aMediaDescr
);
634 ::rtl::OUString aTypeName
= xTypeDetection
->queryTypeByDescriptor( aTempMD
, sal_True
);
637 for ( sal_Int32 nInd
= 0; nInd
< aTempMD
.getLength(); nInd
++ )
638 if ( aTempMD
[nInd
].Name
.equalsAscii( "FilterName" ) )
639 aTempMD
[nInd
].Value
>>= aFilterName
;
641 if ( aFilterName
.getLength() )
643 sal_Int32 nOldLen
= aMediaDescr
.getLength();
644 aMediaDescr
.realloc( nOldLen
+ 1 );
645 aMediaDescr
[nOldLen
].Name
= ::rtl::OUString::createFromAscii( "FilterName" );
646 aMediaDescr
[ nOldLen
].Value
<<= aFilterName
;
649 else if ( aTypeName
.getLength() && !bIgnoreType
)
651 uno::Reference
< container::XNameAccess
> xNameAccess( xTypeDetection
, uno::UNO_QUERY
);
652 uno::Sequence
< beans::PropertyValue
> aTypes
;
654 if ( xNameAccess
.is() && ( xNameAccess
->getByName( aTypeName
) >>= aTypes
) )
656 for ( sal_Int32 nInd
= 0; nInd
< aTypes
.getLength(); nInd
++ )
658 if ( aTypes
[nInd
].Name
.equalsAscii( "PreferredFilter" ) && ( aTypes
[nInd
].Value
>>= aFilterName
) )
660 sal_Int32 nOldLen
= aMediaDescr
.getLength();
661 aMediaDescr
.realloc( nOldLen
+ 1 );
662 aMediaDescr
[nOldLen
].Name
= ::rtl::OUString::createFromAscii( "FilterName" );
663 aMediaDescr
[ nOldLen
].Value
= aTypes
[nInd
].Value
;
674 ::rtl::OUString
MimeConfigurationHelper::UpdateMediaDescriptorWithFilterName(
675 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
,
676 uno::Sequence
< beans::NamedValue
>& aObject
)
678 ::rtl::OUString aDocName
;
679 for ( sal_Int32 nInd
= 0; nInd
< aObject
.getLength(); nInd
++ )
680 if ( aObject
[nInd
].Name
.equalsAscii( "ObjectDocumentServiceName" ) )
682 aObject
[nInd
].Value
>>= aDocName
;
686 OSL_ENSURE( aDocName
.getLength(), "The name must exist at this point!\n" );
689 sal_Bool bNeedsAddition
= sal_True
;
690 for ( sal_Int32 nMedInd
= 0; nMedInd
< aMediaDescr
.getLength(); nMedInd
++ )
691 if ( aMediaDescr
[nMedInd
].Name
.equalsAscii( "DocumentService" ) )
693 aMediaDescr
[nMedInd
].Value
<<= aDocName
;
694 bNeedsAddition
= sal_False
;
698 if ( bNeedsAddition
)
700 sal_Int32 nOldLen
= aMediaDescr
.getLength();
701 aMediaDescr
.realloc( nOldLen
+ 1 );
702 aMediaDescr
[nOldLen
].Name
= ::rtl::OUString::createFromAscii( "DocumentService" );
703 aMediaDescr
[nOldLen
].Value
<<= aDocName
;
706 return UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_True
);
709 sal_Bool
MimeConfigurationHelper::AddFilterNameCheckOwnFile(
710 uno::Sequence
< beans::PropertyValue
>& aMediaDescr
)
712 sal_Bool bResult
= sal_False
;
714 ::rtl::OUString aFilterName
= UpdateMediaDescriptorWithFilterName( aMediaDescr
, sal_False
);
715 if ( aFilterName
.getLength() )
717 sal_Int32 nFlags
= GetFilterFlags( aFilterName
);
718 // check the OWN flag
719 bResult
= ( nFlags
& SFX_FILTER_OWN
);
725 //-----------------------------------------------------------
726 ::rtl::OUString
MimeConfigurationHelper::GetDefaultFilterFromServiceName( const ::rtl::OUString
& aServiceName
, sal_Int32 nVersion
)
728 rtl::OUString aResult
;
730 if ( aServiceName
.getLength() && nVersion
)
733 uno::Reference
< container::XContainerQuery
> xFilterQuery(
735 uno::UNO_QUERY_THROW
);
737 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
738 aSearchRequest
[0].Name
= ::rtl::OUString::createFromAscii( "DocumentService" );
739 aSearchRequest
[0].Value
<<= aServiceName
;
740 aSearchRequest
[1].Name
= ::rtl::OUString::createFromAscii( "FileFormatVersion" );
741 aSearchRequest
[1].Value
<<= nVersion
;
743 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
744 uno::Reference
< container::XEnumeration
> xFilterEnum
=
745 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
747 // use the first filter that is found
748 if ( xFilterEnum
.is() )
749 while ( xFilterEnum
->hasMoreElements() )
751 uno::Sequence
< beans::PropertyValue
> aProps
;
752 if ( xFilterEnum
->nextElement() >>= aProps
)
754 SequenceAsHashMap
aPropsHM( aProps
);
755 sal_Int32 nFlags
= aPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ),
758 // that should be import, export, own filter and not a template filter ( TemplatePath flag )
759 sal_Int32 nRequired
= ( SFX_FILTER_OWN
| SFX_FILTER_EXPORT
| SFX_FILTER_IMPORT
);
760 if ( ( ( nFlags
& nRequired
) == nRequired
) && !( nFlags
& SFX_FILTER_TEMPLATEPATH
) )
762 // if there are more than one filter the preffered one should be used
763 // if there is no preffered filter the first one will be used
764 if ( !aResult
.getLength() || ( nFlags
& SFX_FILTER_PREFERED
) )
765 aResult
= aPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Name" ),
767 if ( nFlags
& SFX_FILTER_PREFERED
)
768 break; // the preffered filter was found
773 catch( uno::Exception
& )
779 //-------------------------------------------------------------------------
780 ::rtl::OUString
MimeConfigurationHelper::GetExportFilterFromImportFilter( const ::rtl::OUString
& aImportFilterName
)
782 ::rtl::OUString aExportFilterName
;
786 if ( aImportFilterName
.getLength() )
788 uno::Reference
< container::XNameAccess
> xFilterFactory(
790 uno::UNO_SET_THROW
);
792 uno::Any aImpFilterAny
= xFilterFactory
->getByName( aImportFilterName
);
793 uno::Sequence
< beans::PropertyValue
> aImpData
;
794 if ( aImpFilterAny
>>= aImpData
)
796 SequenceAsHashMap
aImpFilterHM( aImpData
);
797 sal_Int32 nFlags
= aImpFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ),
800 if ( !( nFlags
& SFX_FILTER_IMPORT
) )
802 OSL_ENSURE( sal_False
, "This is no import filter!" );
803 throw uno::Exception();
806 if ( nFlags
& SFX_FILTER_EXPORT
)
808 aExportFilterName
= aImportFilterName
;
812 ::rtl::OUString aDocumentServiceName
= aImpFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "DocumentService" ), ::rtl::OUString() );
813 ::rtl::OUString aTypeName
= aImpFilterHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Type" ), ::rtl::OUString() );
815 OSL_ENSURE( aDocumentServiceName
.getLength() && aTypeName
.getLength(), "Incomplete filter data!" );
816 if ( aDocumentServiceName
.getLength() && aTypeName
.getLength() )
818 uno::Sequence
< beans::NamedValue
> aSearchRequest( 2 );
819 aSearchRequest
[0].Name
= ::rtl::OUString::createFromAscii( "Type" );
820 aSearchRequest
[0].Value
<<= aTypeName
;
821 aSearchRequest
[1].Name
= ::rtl::OUString::createFromAscii( "DocumentService" );
822 aSearchRequest
[1].Value
<<= aDocumentServiceName
;
824 uno::Sequence
< beans::PropertyValue
> aExportFilterProps
= SearchForFilter(
825 uno::Reference
< container::XContainerQuery
>( xFilterFactory
, uno::UNO_QUERY_THROW
),
828 SFX_FILTER_INTERNAL
);
830 if ( aExportFilterProps
.getLength() )
832 SequenceAsHashMap
aExpPropsHM( aExportFilterProps
);
833 aExportFilterName
= aExpPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Name" ), ::rtl::OUString() );
840 catch( uno::Exception
& )
843 return aExportFilterName
;
846 //-------------------------------------------------------------------------
848 uno::Sequence
< beans::PropertyValue
> MimeConfigurationHelper::SearchForFilter(
849 const uno::Reference
< container::XContainerQuery
>& xFilterQuery
,
850 const uno::Sequence
< beans::NamedValue
>& aSearchRequest
,
851 sal_Int32 nMustFlags
,
852 sal_Int32 nDontFlags
)
854 uno::Sequence
< beans::PropertyValue
> aFilterProps
;
855 uno::Reference
< container::XEnumeration
> xFilterEnum
=
856 xFilterQuery
->createSubSetEnumerationByProperties( aSearchRequest
);
858 // the first default filter will be taken,
859 // if there is no filter with flag default the first acceptable filter will be taken
860 if ( xFilterEnum
.is() )
862 while ( xFilterEnum
->hasMoreElements() )
864 uno::Sequence
< beans::PropertyValue
> aProps
;
865 if ( xFilterEnum
->nextElement() >>= aProps
)
867 SequenceAsHashMap
aPropsHM( aProps
);
868 sal_Int32 nFlags
= aPropsHM
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Flags" ),
870 if ( ( ( nFlags
& nMustFlags
) == nMustFlags
) && !( nFlags
& nDontFlags
) )
872 if ( ( nFlags
& SFX_FILTER_DEFAULT
) == SFX_FILTER_DEFAULT
)
874 aFilterProps
= aProps
;
877 else if ( !aFilterProps
.getLength() )
878 aFilterProps
= aProps
;
888 //-------------------------------------------------------------------------
889 sal_Bool
MimeConfigurationHelper::ClassIDsEqual( const uno::Sequence
< sal_Int8
>& aClassID1
, const uno::Sequence
< sal_Int8
>& aClassID2
)
891 if ( aClassID1
.getLength() != aClassID2
.getLength() )
894 for ( sal_Int32 nInd
= 0; nInd
< aClassID1
.getLength(); nInd
++ )
895 if ( aClassID1
[nInd
] != aClassID2
[nInd
] )
901 //-------------------------------------------------------------------------
902 uno::Sequence
< sal_Int8
> MimeConfigurationHelper::GetSequenceClassID( sal_uInt32 n1
, sal_uInt16 n2
, sal_uInt16 n3
,
903 sal_uInt8 b8
, sal_uInt8 b9
, sal_uInt8 b10
, sal_uInt8 b11
,
904 sal_uInt8 b12
, sal_uInt8 b13
, sal_uInt8 b14
, sal_uInt8 b15
)
906 uno::Sequence
< sal_Int8
> aResult( 16 );
907 aResult
[0] = (sal_Int8
)( n1
>> 24 );
908 aResult
[1] = (sal_Int8
)( ( n1
<< 8 ) >> 24 );
909 aResult
[2] = (sal_Int8
)( ( n1
<< 16 ) >> 24 );
910 aResult
[3] = (sal_Int8
)( ( n1
<< 24 ) >> 24 );
911 aResult
[4] = (sal_Int8
)( n2
>> 8 );
912 aResult
[5] = (sal_Int8
)( ( n2
<< 8 ) >> 8 );
913 aResult
[6] = (sal_Int8
)( n3
>> 8 );
914 aResult
[7] = (sal_Int8
)( ( n3
<< 8 ) >> 8 );
927 //-------------------------------------------------------------------------
928 uno::Sequence
<sal_Int8
> MimeConfigurationHelper::GetSequenceClassIDFromObjectName(const ::rtl::OUString
& _sObjectName
)
930 uno::Sequence
<sal_Int8
> aClassId
;
931 uno::Reference
< container::XNameAccess
> xObjectNames
= GetConfigurationByPath(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Embedding/ObjectNames")));
932 uno::Reference
< container::XNameAccess
> xProps
;
933 if ( xObjectNames
.is() && (xObjectNames
->getByName(_sObjectName
) >>= xProps
) && xProps
.is() )
935 ::rtl::OUString sValue
;
936 xProps
->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ClassID"))) >>= sValue
;
937 aClassId
= GetSequenceClassIDRepresentation(sValue
);