LibreOffice Module comphelper (master)  1
mimeconfighelper.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/configuration/theDefaultProvider.hpp>
22 #include <com/sun/star/container/XContainerQuery.hpp>
23 #include <com/sun/star/container/XNameAccess.hpp>
24 #include <com/sun/star/embed/VerbDescriptor.hpp>
25 #include <com/sun/star/document/XTypeDetection.hpp>
26 
27 #include <osl/diagnose.h>
28 
29 #include <comphelper/fileformat.h>
31 #include <comphelper/classids.hxx>
35 #include <rtl/ustrbuf.hxx>
36 
37 
38 using namespace ::com::sun::star;
39 using namespace comphelper;
40 
41 
42 MimeConfigurationHelper::MimeConfigurationHelper( const uno::Reference< uno::XComponentContext >& rxContext )
43 : m_xContext( rxContext )
44 {
45  if ( !m_xContext.is() )
46  throw uno::RuntimeException();
47 }
48 
49 
50 OUString MimeConfigurationHelper::GetStringClassIDRepresentation( const uno::Sequence< sal_Int8 >& aClassID )
51 {
52  OUStringBuffer aResult;
53 
54  if ( aClassID.getLength() == 16 )
55  {
56  for ( sal_Int32 nInd = 0; nInd < aClassID.getLength(); nInd++ )
57  {
58  if ( nInd == 4 || nInd == 6 || nInd == 8 || nInd == 10 )
59  aResult.append("-");
60 
61  sal_Int32 nDigit1 = static_cast<sal_Int32>( static_cast<sal_uInt8>(aClassID[nInd]) / 16 );
62  sal_Int32 nDigit2 = static_cast<sal_uInt8>(aClassID[nInd]) % 16;
63  aResult.append(OUString::number( nDigit1, 16 )).append(OUString::number( nDigit2, 16 ));
64  }
65  }
66 
67  return aResult.makeStringAndClear();
68 }
69 
70 
72 {
73  if ( aChar >= '0' && aChar <= '9' )
74  return aChar - '0';
75  else if ( aChar >= 'a' && aChar <= 'f' )
76  return aChar - 'a' + 10;
77  else if ( aChar >= 'A' && aChar <= 'F' )
78  return aChar - 'A' + 10;
79  else
80  return 16;
81 }
82 
83 
84 uno::Sequence< sal_Int8 > MimeConfigurationHelper::GetSequenceClassIDRepresentation( const OUString& aClassID )
85 {
86  sal_Int32 nLength = aClassID.getLength();
87  if ( nLength == 36 )
88  {
89  OString aCharClassID = OUStringToOString( aClassID, RTL_TEXTENCODING_ASCII_US );
90  uno::Sequence< sal_Int8 > aResult( 16 );
91 
92  sal_Int32 nStrPointer = 0;
93  sal_Int32 nSeqInd = 0;
94  while( nSeqInd < 16 && nStrPointer + 1 < nLength )
95  {
96  sal_uInt8 nDigit1 = GetDigit_Impl( aCharClassID[nStrPointer++] );
97  sal_uInt8 nDigit2 = GetDigit_Impl( aCharClassID[nStrPointer++] );
98 
99  if ( nDigit1 > 15 || nDigit2 > 15 )
100  break;
101 
102  aResult[nSeqInd++] = static_cast<sal_Int8>( nDigit1 * 16 + nDigit2 );
103 
104  if ( nStrPointer < nLength && aCharClassID[nStrPointer] == '-' )
105  nStrPointer++;
106  }
107 
108  if ( nSeqInd == 16 && nStrPointer == nLength )
109  return aResult;
110  }
111 
112  return uno::Sequence< sal_Int8 >();
113 }
114 
115 
116 uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetConfigurationByPath( const OUString& aPath )
117 {
118  osl::MutexGuard aGuard( m_aMutex );
119 
120  uno::Reference< container::XNameAccess > xConfig;
121 
122  try
123  {
124  if ( !m_xConfigProvider.is() )
125  m_xConfigProvider = configuration::theDefaultProvider::get( m_xContext );
126 
127  uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
128  {
129  {"nodepath", uno::Any(aPath)}
130  }));
131  xConfig.set( m_xConfigProvider->createInstanceWithArguments(
132  "com.sun.star.configuration.ConfigurationAccess",
133  aArgs ),
134  uno::UNO_QUERY );
135  }
136  catch( uno::Exception& )
137  {}
138 
139  return xConfig;
140 }
141 
142 
143 uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetObjConfiguration()
144 {
145  osl::MutexGuard aGuard( m_aMutex );
146 
147  if ( !m_xObjectConfig.is() )
149  "/org.openoffice.Office.Embedding/Objects" );
150 
151  return m_xObjectConfig;
152 }
153 
154 
155 uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetVerbsConfiguration()
156 {
157  osl::MutexGuard aGuard( m_aMutex );
158 
159  if ( !m_xVerbsConfig.is() )
161  "/org.openoffice.Office.Embedding/Verbs");
162 
163  return m_xVerbsConfig;
164 }
165 
166 
167 uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetMediaTypeConfiguration()
168 {
169  osl::MutexGuard aGuard( m_aMutex );
170 
171  if ( !m_xMediaTypeConfig.is() )
173  "/org.openoffice.Office.Embedding/MimeTypeClassIDRelations");
174 
175  return m_xMediaTypeConfig;
176 }
177 
178 
179 uno::Reference< container::XNameAccess > MimeConfigurationHelper::GetFilterFactory()
180 {
181  osl::MutexGuard aGuard( m_aMutex );
182 
183  if ( !m_xFilterFactory.is() )
184  m_xFilterFactory.set(
185  m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", m_xContext),
186  uno::UNO_QUERY );
187 
188  return m_xFilterFactory;
189 }
190 
191 
192 OUString MimeConfigurationHelper::GetDocServiceNameFromFilter( const OUString& aFilterName )
193 {
194  OUString aDocServiceName;
195 
196  try
197  {
198  uno::Reference< container::XNameAccess > xFilterFactory(
200  uno::UNO_SET_THROW );
201 
202  uno::Any aFilterAnyData = xFilterFactory->getByName( aFilterName );
203  uno::Sequence< beans::PropertyValue > aFilterData;
204  if ( aFilterAnyData >>= aFilterData )
205  {
206  for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
207  if ( aFilterData[nInd].Name == "DocumentService" )
208  aFilterData[nInd].Value >>= aDocServiceName;
209  }
210  }
211  catch( uno::Exception& )
212  {}
213 
214  return aDocServiceName;
215 }
216 
217 
218 OUString MimeConfigurationHelper::GetDocServiceNameFromMediaType( const OUString& aMediaType )
219 {
220  uno::Reference< container::XContainerQuery > xTypeCFG(
221  m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext),
222  uno::UNO_QUERY );
223 
224  if ( xTypeCFG.is() )
225  {
226  try
227  {
228  // make query for all types matching the properties
229  uno::Sequence < beans::NamedValue > aSeq { { "MediaType", css::uno::Any(aMediaType) } };
230 
231  uno::Reference < container::XEnumeration > xEnum = xTypeCFG->createSubSetEnumerationByProperties( aSeq );
232  while ( xEnum->hasMoreElements() )
233  {
234  uno::Sequence< beans::PropertyValue > aType;
235  if ( xEnum->nextElement() >>= aType )
236  {
237  for ( sal_Int32 nInd = 0; nInd < aType.getLength(); nInd++ )
238  {
239  OUString aFilterName;
240  if ( aType[nInd].Name == "PreferredFilter"
241  && ( aType[nInd].Value >>= aFilterName ) && !aFilterName.isEmpty() )
242  {
243  OUString aDocumentName = GetDocServiceNameFromFilter( aFilterName );
244  if ( !aDocumentName.isEmpty() )
245  return aDocumentName;
246  }
247  }
248  }
249  }
250  }
251  catch( uno::Exception& )
252  {}
253  }
254 
255  return OUString();
256 }
257 
258 
259 bool MimeConfigurationHelper::GetVerbByShortcut( const OUString& aVerbShortcut,
260  embed::VerbDescriptor& aDescriptor )
261 {
262  bool bResult = false;
263 
264  uno::Reference< container::XNameAccess > xVerbsConfig = GetVerbsConfiguration();
265  uno::Reference< container::XNameAccess > xVerbsProps;
266  try
267  {
268  if ( xVerbsConfig.is() && ( xVerbsConfig->getByName( aVerbShortcut ) >>= xVerbsProps ) && xVerbsProps.is() )
269  {
270  embed::VerbDescriptor aTempDescr;
271  if ( ( xVerbsProps->getByName("VerbID") >>= aTempDescr.VerbID )
272  && ( xVerbsProps->getByName("VerbUIName") >>= aTempDescr.VerbName )
273  && ( xVerbsProps->getByName("VerbFlags") >>= aTempDescr.VerbFlags )
274  && ( xVerbsProps->getByName("VerbAttributes") >>= aTempDescr.VerbAttributes ) )
275  {
276  aDescriptor = aTempDescr;
277  bResult = true;
278  }
279  }
280  }
281  catch( uno::Exception& )
282  {
283  }
284 
285  return bResult;
286 }
287 
288 
289 uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjPropsFromConfigEntry(
290  const uno::Sequence< sal_Int8 >& aClassID,
291  const uno::Reference< container::XNameAccess >& xObjectProps )
292 {
293  uno::Sequence< beans::NamedValue > aResult;
294 
295  if ( aClassID.getLength() == 16 )
296  {
297  try
298  {
299  uno::Sequence< OUString > aObjPropNames = xObjectProps->getElementNames();
300 
301  aResult.realloc( aObjPropNames.getLength() + 1 );
302  aResult[0].Name = "ClassID";
303  aResult[0].Value <<= aClassID;
304 
305  for ( sal_Int32 nInd = 0; nInd < aObjPropNames.getLength(); nInd++ )
306  {
307  aResult[nInd + 1].Name = aObjPropNames[nInd];
308 
309  if ( aObjPropNames[nInd] == "ObjectVerbs" )
310  {
311  uno::Sequence< OUString > aVerbShortcuts;
312  if ( !(xObjectProps->getByName( aObjPropNames[nInd] ) >>= aVerbShortcuts) )
313  throw uno::RuntimeException();
314  uno::Sequence< embed::VerbDescriptor > aVerbDescriptors( aVerbShortcuts.getLength() );
315  for ( sal_Int32 nVerbI = 0; nVerbI < aVerbShortcuts.getLength(); nVerbI++ )
316  if ( !GetVerbByShortcut( aVerbShortcuts[nVerbI], aVerbDescriptors[nVerbI] ) )
317  throw uno::RuntimeException();
318 
319  aResult[nInd+1].Value <<= aVerbDescriptors;
320  }
321  else
322  aResult[nInd+1].Value = xObjectProps->getByName( aObjPropNames[nInd] );
323  }
324  }
325  catch( uno::Exception& )
326  {
327  aResult.realloc( 0 );
328  }
329  }
330 
331  return aResult;
332 }
333 
334 
336 {
337  OUString aStringClassID;
338 
339  uno::Reference< container::XNameAccess > xMediaTypeConfig = GetMediaTypeConfiguration();
340  try
341  {
342  if ( xMediaTypeConfig.is() )
343  xMediaTypeConfig->getByName( aMediaType ) >>= aStringClassID;
344  }
345  catch( uno::Exception& )
346  {
347  }
348 
349  return aStringClassID;
350 
351 }
352 
353 
355  const OUString& aStringClassID )
356 {
357  uno::Sequence< beans::NamedValue > aObjProps;
358 
359  uno::Sequence< sal_Int8 > aClassID = GetSequenceClassIDRepresentation( aStringClassID );
360  if ( ClassIDsEqual( aClassID, GetSequenceClassID( SO3_DUMMY_CLASSID ) ) )
361  {
362  aObjProps.realloc(2);
363  aObjProps[0].Name = "ObjectFactory";
364  aObjProps[0].Value <<= OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
365  aObjProps[1].Name = "ClassID";
366  aObjProps[1].Value <<= aClassID;
367  return aObjProps;
368  }
369 
370  if ( aClassID.getLength() == 16 )
371  {
372  uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration();
373  uno::Reference< container::XNameAccess > xObjectProps;
374  try
375  {
376  // TODO/LATER: allow to provide ClassID string in any format, only digits are counted
377  if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() )
378  aObjProps = GetObjPropsFromConfigEntry( aClassID, xObjectProps );
379  }
380  catch( uno::Exception& )
381  {
382  }
383  }
384 
385  return aObjProps;
386 }
387 
388 
389 uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByClassID(
390  const uno::Sequence< sal_Int8 >& aClassID )
391 {
392  uno::Sequence< beans::NamedValue > aObjProps;
393  if ( ClassIDsEqual( aClassID, GetSequenceClassID( SO3_DUMMY_CLASSID ) ) )
394  {
395  aObjProps.realloc(2);
396  aObjProps[0].Name = "ObjectFactory";
397  aObjProps[0].Value <<= OUString( "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory" );
398  aObjProps[1].Name = "ClassID";
399  aObjProps[1].Value <<= aClassID;
400  }
401 
402  OUString aStringClassID = GetStringClassIDRepresentation( aClassID );
403  if ( !aStringClassID.isEmpty() )
404  {
405  uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration();
406  uno::Reference< container::XNameAccess > xObjectProps;
407  try
408  {
409  if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() )
410  aObjProps = GetObjPropsFromConfigEntry( aClassID, xObjectProps );
411  }
412  catch( uno::Exception& )
413  {
414  }
415  }
416 
417  return aObjProps;
418 }
419 
420 
421 uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByMediaType( const OUString& aMediaType )
422 {
423  uno::Sequence< beans::NamedValue > aObject =
425  if ( aObject.hasElements() )
426  return aObject;
427 
428  OUString aDocumentName = GetDocServiceNameFromMediaType( aMediaType );
429  if ( !aDocumentName.isEmpty() )
430  return GetObjectPropsByDocumentName( aDocumentName );
431 
432  return uno::Sequence< beans::NamedValue >();
433 }
434 
435 
436 uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByFilter( const OUString& aFilterName )
437 {
438  OUString aDocumentName = GetDocServiceNameFromFilter( aFilterName );
439  if ( !aDocumentName.isEmpty() )
440  return GetObjectPropsByDocumentName( aDocumentName );
441 
442  return uno::Sequence< beans::NamedValue >();
443 }
444 
445 
446 uno::Sequence< beans::NamedValue > MimeConfigurationHelper::GetObjectPropsByDocumentName( const OUString& aDocName )
447 {
448  if ( !aDocName.isEmpty() )
449  {
450  uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration();
451  if ( xObjConfig.is() )
452  {
453  try
454  {
455  uno::Sequence< OUString > aClassIDs = xObjConfig->getElementNames();
456  for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ )
457  {
458  uno::Reference< container::XNameAccess > xObjectProps;
459  OUString aEntryDocName;
460 
461  if ( ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is()
462  && ( xObjectProps->getByName("ObjectDocumentServiceName") >>= aEntryDocName )
463  && aEntryDocName == aDocName )
464  {
466  xObjectProps );
467  }
468  }
469  }
470  catch( uno::Exception& )
471  {}
472  }
473  }
474 
475  return uno::Sequence< beans::NamedValue >();
476 }
477 
478 
479 OUString MimeConfigurationHelper::GetFactoryNameByClassID( const uno::Sequence< sal_Int8 >& aClassID )
480 {
482 }
483 
484 
485 OUString MimeConfigurationHelper::GetFactoryNameByStringClassID( const OUString& aStringClassID )
486 {
487  OUString aResult;
488 
489  if ( !aStringClassID.isEmpty() )
490  {
491  uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration();
492  uno::Reference< container::XNameAccess > xObjectProps;
493  try
494  {
495  if ( xObjConfig.is() && ( xObjConfig->getByName( aStringClassID.toAsciiUpperCase() ) >>= xObjectProps ) && xObjectProps.is() )
496  xObjectProps->getByName("ObjectFactory") >>= aResult;
497  }
498  catch( uno::Exception& )
499  {
500  uno::Sequence< sal_Int8 > aClassID = GetSequenceClassIDRepresentation( aStringClassID );
501  if ( ClassIDsEqual( aClassID, GetSequenceClassID( SO3_DUMMY_CLASSID ) ) )
502  return "com.sun.star.embed.OOoSpecialEmbeddedObjectFactory";
503  }
504  }
505 
506  return aResult;
507 }
508 
509 
510 OUString MimeConfigurationHelper::GetFactoryNameByDocumentName( const OUString& aDocName )
511 {
512  OUString aResult;
513 
514  if ( !aDocName.isEmpty() )
515  {
516  uno::Reference< container::XNameAccess > xObjConfig = GetObjConfiguration();
517  if ( xObjConfig.is() )
518  {
519  try
520  {
521  uno::Sequence< OUString > aClassIDs = xObjConfig->getElementNames();
522  for ( sal_Int32 nInd = 0; nInd < aClassIDs.getLength(); nInd++ )
523  {
524  uno::Reference< container::XNameAccess > xObjectProps;
525  OUString aEntryDocName;
526 
527  if ( ( xObjConfig->getByName( aClassIDs[nInd] ) >>= xObjectProps ) && xObjectProps.is()
528  && ( xObjectProps->getByName( "ObjectDocumentServiceName" ) >>= aEntryDocName )
529  && aEntryDocName == aDocName )
530  {
531  xObjectProps->getByName("ObjectFactory") >>= aResult;
532  break;
533  }
534  }
535  }
536  catch( uno::Exception& )
537  {}
538  }
539  }
540 
541  return aResult;
542 }
543 
544 
545 OUString MimeConfigurationHelper::GetFactoryNameByMediaType( const OUString& aMediaType )
546 {
547  OUString aResult = GetFactoryNameByStringClassID( GetExplicitlyRegisteredObjClassID( aMediaType ) );
548 
549  if ( aResult.isEmpty() )
550  {
551  OUString aDocumentName = GetDocServiceNameFromMediaType( aMediaType );
552  if ( !aDocumentName.isEmpty() )
553  aResult = GetFactoryNameByDocumentName( aDocumentName );
554  }
555 
556  return aResult;
557 }
558 
559 
561  uno::Sequence< beans::PropertyValue >& aMediaDescr,
562  bool bIgnoreType )
563 {
564  OUString aFilterName;
565 
566  for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ )
567  if ( aMediaDescr[nInd].Name == "FilterName" )
568  aMediaDescr[nInd].Value >>= aFilterName;
569 
570  if ( aFilterName.isEmpty() )
571  {
572  // filter name is not specified, so type detection should be done
573 
574  uno::Reference< document::XTypeDetection > xTypeDetection(
575  m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_xContext),
576  uno::UNO_QUERY_THROW );
577 
578  // typedetection can change the mode, add a stream and so on, thus a copy should be used
579  uno::Sequence< beans::PropertyValue > aTempMD( aMediaDescr );
580 
581  // get TypeName
582  OUString aTypeName = xTypeDetection->queryTypeByDescriptor( aTempMD, true );
583 
584  // get FilterName
585  for ( sal_Int32 nInd = 0; nInd < aTempMD.getLength(); nInd++ )
586  if ( aTempMD[nInd].Name == "FilterName" )
587  aTempMD[nInd].Value >>= aFilterName;
588 
589  if ( !aFilterName.isEmpty() )
590  {
591  sal_Int32 nOldLen = aMediaDescr.getLength();
592  aMediaDescr.realloc( nOldLen + 1 );
593  aMediaDescr[nOldLen].Name = "FilterName";
594  aMediaDescr[ nOldLen ].Value <<= aFilterName;
595 
596  }
597  else if ( !aTypeName.isEmpty() && !bIgnoreType )
598  {
599  uno::Reference< container::XNameAccess > xNameAccess( xTypeDetection, uno::UNO_QUERY );
600  uno::Sequence< beans::PropertyValue > aTypes;
601 
602  if ( xNameAccess.is() && ( xNameAccess->getByName( aTypeName ) >>= aTypes ) )
603  {
604  for ( sal_Int32 nInd = 0; nInd < aTypes.getLength(); nInd++ )
605  {
606  if ( aTypes[nInd].Name == "PreferredFilter" && ( aTypes[nInd].Value >>= aFilterName ) )
607  {
608  sal_Int32 nOldLen = aMediaDescr.getLength();
609  aMediaDescr.realloc( nOldLen + 1 );
610  aMediaDescr[nOldLen].Name = "FilterName";
611  aMediaDescr[ nOldLen ].Value = aTypes[nInd].Value;
612  break;
613  }
614  }
615  }
616  }
617  }
618 
619  return aFilterName;
620 }
621 
623  uno::Sequence< beans::PropertyValue >& aMediaDescr,
624  uno::Sequence< beans::NamedValue >& aObject )
625 {
626  OUString aDocName;
627  for ( sal_Int32 nInd = 0; nInd < aObject.getLength(); nInd++ )
628  if ( aObject[nInd].Name == "ObjectDocumentServiceName" )
629  {
630  aObject[nInd].Value >>= aDocName;
631  break;
632  }
633 
634  OSL_ENSURE( !aDocName.isEmpty(), "The name must exist at this point!" );
635 
636 
637  bool bNeedsAddition = true;
638  for ( sal_Int32 nMedInd = 0; nMedInd < aMediaDescr.getLength(); nMedInd++ )
639  if ( aMediaDescr[nMedInd].Name == "DocumentService" )
640  {
641  aMediaDescr[nMedInd].Value <<= aDocName;
642  bNeedsAddition = false;
643  break;
644  }
645 
646  if ( bNeedsAddition )
647  {
648  sal_Int32 nOldLen = aMediaDescr.getLength();
649  aMediaDescr.realloc( nOldLen + 1 );
650  aMediaDescr[nOldLen].Name = "DocumentService";
651  aMediaDescr[nOldLen].Value <<= aDocName;
652  }
653 
654  return UpdateMediaDescriptorWithFilterName( aMediaDescr, true );
655 }
656 
657 #ifdef _WIN32
658 
659 SfxFilterFlags MimeConfigurationHelper::GetFilterFlags( const OUString& aFilterName )
660 {
662  try
663  {
664  if ( !aFilterName.isEmpty() )
665  {
666  uno::Reference< container::XNameAccess > xFilterFactory(
668  uno::UNO_SET_THROW );
669 
670  uno::Any aFilterAny = xFilterFactory->getByName( aFilterName );
671  uno::Sequence< beans::PropertyValue > aData;
672  if ( aFilterAny >>= aData )
673  {
674  SequenceAsHashMap aFilterHM( aData );
675  nFlags = static_cast<SfxFilterFlags>(aFilterHM.getUnpackedValueOrDefault( "Flags", sal_Int32(0) ));
676  }
677  }
678  } catch( uno::Exception& )
679  {}
680 
681  return nFlags;
682 }
683 
684 bool MimeConfigurationHelper::AddFilterNameCheckOwnFile(
685  uno::Sequence< beans::PropertyValue >& aMediaDescr )
686 {
687  OUString aFilterName = UpdateMediaDescriptorWithFilterName( aMediaDescr, false );
688  if ( !aFilterName.isEmpty() )
689  {
690  SfxFilterFlags nFlags = GetFilterFlags( aFilterName );
691  // check the OWN flag
692  return bool(nFlags & SfxFilterFlags::OWN);
693  }
694 
695  return false;
696 }
697 
698 #endif
699 
700 OUString MimeConfigurationHelper::GetDefaultFilterFromServiceName( const OUString& aServiceName, sal_Int32 nVersion )
701 {
702  OUString aResult;
703 
704  if ( !aServiceName.isEmpty() && nVersion )
705  try
706  {
707  uno::Reference< container::XContainerQuery > xFilterQuery(
709  uno::UNO_QUERY_THROW );
710 
711  uno::Sequence< beans::NamedValue > aSearchRequest
712  {
713  { "DocumentService", css::uno::Any(aServiceName) },
714  { "FileFormatVersion", css::uno::Any(nVersion) }
715  };
716 
717  uno::Reference< container::XEnumeration > xFilterEnum =
718  xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest );
719 
720  // use the first filter that is found
721  if ( xFilterEnum.is() )
722  while ( xFilterEnum->hasMoreElements() )
723  {
724  uno::Sequence< beans::PropertyValue > aProps;
725  if ( xFilterEnum->nextElement() >>= aProps )
726  {
727  SequenceAsHashMap aPropsHM( aProps );
728  SfxFilterFlags nFlags = static_cast<SfxFilterFlags>(aPropsHM.getUnpackedValueOrDefault( "Flags", sal_Int32(0) ));
729 
730  // that should be import, export, own filter and not a template filter ( TemplatePath flag )
731  SfxFilterFlags const nRequired = SfxFilterFlags::OWN
732  // fdo#78159 for OOoXML, there is code to convert
733  // to ODF in OCommonEmbeddedObject::store*
734  // so accept it even though there's no export
737  if ( ( ( nFlags & nRequired ) == nRequired ) && !( nFlags & SfxFilterFlags::TEMPLATEPATH ) )
738  {
739  // if there are more than one filter the preferred one should be used
740  // if there is no preferred filter the first one will be used
741  if ( aResult.isEmpty() || ( nFlags & SfxFilterFlags::PREFERED ) )
742  aResult = aPropsHM.getUnpackedValueOrDefault( "Name", OUString() );
743  if ( nFlags & SfxFilterFlags::PREFERED )
744  break; // the preferred filter was found
745  }
746  }
747  }
748  }
749  catch( uno::Exception& )
750  {}
751 
752  return aResult;
753 }
754 
755 
756 OUString MimeConfigurationHelper::GetExportFilterFromImportFilter( const OUString& aImportFilterName )
757 {
758  OUString aExportFilterName;
759 
760  try
761  {
762  if ( !aImportFilterName.isEmpty() )
763  {
764  uno::Reference< container::XNameAccess > xFilterFactory(
766  uno::UNO_SET_THROW );
767 
768  uno::Any aImpFilterAny = xFilterFactory->getByName( aImportFilterName );
769  uno::Sequence< beans::PropertyValue > aImpData;
770  if ( aImpFilterAny >>= aImpData )
771  {
772  SequenceAsHashMap aImpFilterHM( aImpData );
773  SfxFilterFlags nFlags = static_cast<SfxFilterFlags>(aImpFilterHM.getUnpackedValueOrDefault( "Flags", sal_Int32(0) ));
774 
775  if ( !( nFlags & SfxFilterFlags::IMPORT ) )
776  {
777  OSL_FAIL( "This is no import filter!" );
778  throw uno::Exception("this is no import filter", nullptr);
779  }
780 
781  if ( nFlags & SfxFilterFlags::EXPORT )
782  {
783  aExportFilterName = aImportFilterName;
784  }
785  else
786  {
787  OUString aDocumentServiceName = aImpFilterHM.getUnpackedValueOrDefault( "DocumentService", OUString() );
788  OUString aTypeName = aImpFilterHM.getUnpackedValueOrDefault( "Type", OUString() );
789 
790  OSL_ENSURE( !aDocumentServiceName.isEmpty() && !aTypeName.isEmpty(), "Incomplete filter data!" );
791  if ( !(aDocumentServiceName.isEmpty() || aTypeName.isEmpty()) )
792  {
793  uno::Sequence< beans::NamedValue > aSearchRequest
794  {
795  { "Type", css::uno::Any(aTypeName) },
796  { "DocumentService", css::uno::Any(aDocumentServiceName) }
797  };
798 
799  uno::Sequence< beans::PropertyValue > aExportFilterProps = SearchForFilter(
800  uno::Reference< container::XContainerQuery >( xFilterFactory, uno::UNO_QUERY_THROW ),
801  aSearchRequest,
802  SfxFilterFlags::EXPORT,
804 
805  if ( aExportFilterProps.hasElements() )
806  {
807  SequenceAsHashMap aExpPropsHM( aExportFilterProps );
808  aExportFilterName = aExpPropsHM.getUnpackedValueOrDefault( "Name", OUString() );
809  }
810  }
811  }
812  }
813  }
814  }
815  catch( uno::Exception& )
816  {}
817 
818  return aExportFilterName;
819 }
820 
821 
822 // static
823 uno::Sequence< beans::PropertyValue > MimeConfigurationHelper::SearchForFilter(
824  const uno::Reference< container::XContainerQuery >& xFilterQuery,
825  const uno::Sequence< beans::NamedValue >& aSearchRequest,
826  SfxFilterFlags nMustFlags,
827  SfxFilterFlags nDontFlags )
828 {
829  uno::Sequence< beans::PropertyValue > aFilterProps;
830  uno::Reference< container::XEnumeration > xFilterEnum =
831  xFilterQuery->createSubSetEnumerationByProperties( aSearchRequest );
832 
833  // the first default filter will be taken,
834  // if there is no filter with flag default the first acceptable filter will be taken
835  if ( xFilterEnum.is() )
836  {
837  while ( xFilterEnum->hasMoreElements() )
838  {
839  uno::Sequence< beans::PropertyValue > aProps;
840  if ( xFilterEnum->nextElement() >>= aProps )
841  {
842  SequenceAsHashMap aPropsHM( aProps );
843  SfxFilterFlags nFlags = static_cast<SfxFilterFlags>(aPropsHM.getUnpackedValueOrDefault("Flags",
844  sal_Int32(0) ));
845  if ( ( ( nFlags & nMustFlags ) == nMustFlags ) && !( nFlags & nDontFlags ) )
846  {
847  if ( ( nFlags & SfxFilterFlags::DEFAULT ) == SfxFilterFlags::DEFAULT )
848  {
849  aFilterProps = aProps;
850  break;
851  }
852  else if ( !aFilterProps.hasElements() )
853  aFilterProps = aProps;
854  }
855  }
856  }
857  }
858 
859  return aFilterProps;
860 }
861 
862 
863 bool MimeConfigurationHelper::ClassIDsEqual( const uno::Sequence< sal_Int8 >& aClassID1, const uno::Sequence< sal_Int8 >& aClassID2 )
864 {
865  if ( aClassID1.getLength() != aClassID2.getLength() )
866  return false;
867 
868  for ( sal_Int32 nInd = 0; nInd < aClassID1.getLength(); nInd++ )
869  if ( aClassID1[nInd] != aClassID2[nInd] )
870  return false;
871 
872  return true;
873 }
874 
875 
876 uno::Sequence< sal_Int8 > MimeConfigurationHelper::GetSequenceClassID( sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3,
877  sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11,
878  sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15 )
879 {
880  uno::Sequence< sal_Int8 > aResult( 16 );
881  aResult[0] = static_cast<sal_Int8>( n1 >> 24 );
882  aResult[1] = static_cast<sal_Int8>( ( n1 << 8 ) >> 24 );
883  aResult[2] = static_cast<sal_Int8>( ( n1 << 16 ) >> 24 );
884  aResult[3] = static_cast<sal_Int8>( ( n1 << 24 ) >> 24 );
885  aResult[4] = static_cast<sal_Int8>( n2 >> 8 );
886  aResult[5] = static_cast<sal_Int8>( ( n2 << 8 ) >> 8 );
887  aResult[6] = static_cast<sal_Int8>( n3 >> 8 );
888  aResult[7] = static_cast<sal_Int8>( ( n3 << 8 ) >> 8 );
889  aResult[8] = b8;
890  aResult[9] = b9;
891  aResult[10] = b10;
892  aResult[11] = b11;
893  aResult[12] = b12;
894  aResult[13] = b13;
895  aResult[14] = b14;
896  aResult[15] = b15;
897 
898  return aResult;
899 }
900 
901 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::container::XNameAccess > GetVerbsConfiguration()
const char *const aClassID
static sal_uInt8 GetDigit_Impl(sal_Char aChar)
OUString GetDefaultFilterFromServiceName(const OUString &aServName, sal_Int32 nVersion)
const char aData[]
css::uno::Reference< css::uno::XComponentContext > m_xContext
signed char sal_Int8
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByDocumentName(const OUString &aDocumentName)
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByFilter(const OUString &aFilterName)
bool GetVerbByShortcut(const OUString &aVerbShortcut, css::embed::VerbDescriptor &aDescriptor)
OUString UpdateMediaDescriptorWithFilterName(css::uno::Sequence< css::beans::PropertyValue > &aMediaDescr, bool bIgnoreType)
OUString Name
OUString GetExportFilterFromImportFilter(const OUString &aImportFilterName)
css::uno::Reference< css::container::XNameAccess > GetFilterFactory()
Value
MimeConfigurationHelper(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
char sal_Char
OUString GetFactoryNameByStringClassID(const OUString &aStringClassID)
OUString GetDocServiceNameFromMediaType(const OUString &aMediaType)
css::uno::Reference< css::container::XNameAccess > GetMediaTypeConfiguration()
css::uno::Reference< css::container::XNameAccess > m_xVerbsConfig
#define SOFFICE_FILEFORMAT_60
Definition: fileformat.h:28
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
check if the specified item exists and return its (unpacked!) value or it returns the specified defau...
OUString GetFactoryNameByMediaType(const OUString &aMediaType)
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
Init list for property sequences that wrap the PropertyValues in Anys.
#define SO3_DUMMY_CLASSID
Definition: classids.hxx:312
OUString GetFactoryNameByClassID(const css::uno::Sequence< sal_Int8 > &aClassID)
static css::uno::Sequence< sal_Int8 > GetSequenceClassIDRepresentation(const OUString &aClassID)
OUString GetExplicitlyRegisteredObjClassID(const OUString &aMediaType)
Object Value
OUString GetDocServiceNameFromFilter(const OUString &aFilterName)
static bool ClassIDsEqual(const css::uno::Sequence< sal_Int8 > &aClassID1, const css::uno::Sequence< sal_Int8 > &aClassID2)
static OUString GetStringClassIDRepresentation(const css::uno::Sequence< sal_Int8 > &aClassID)
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
static css::uno::Sequence< css::beans::PropertyValue > SearchForFilter(const css::uno::Reference< css::container::XContainerQuery > &xFilterQuery, const css::uno::Sequence< css::beans::NamedValue > &aSearchRequest, SfxFilterFlags nMustFlags, SfxFilterFlags nDontFlags)
static css::uno::Sequence< sal_Int8 > GetSequenceClassID(sal_uInt32 n1, sal_uInt16 n2, sal_uInt16 n3, sal_uInt8 b8, sal_uInt8 b9, sal_uInt8 b10, sal_uInt8 b11, sal_uInt8 b12, sal_uInt8 b13, sal_uInt8 b14, sal_uInt8 b15)
OUString GetFactoryNameByDocumentName(const OUString &aDocName)
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByStringClassID(const OUString &aStringClassID)
unsigned char sal_uInt8
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByClassID(const css::uno::Sequence< sal_Int8 > &aClassID)
css::uno::Reference< css::container::XNameAccess > GetConfigurationByPath(const OUString &aPath)
css::uno::Reference< css::container::XNameAccess > GetObjConfiguration()
css::uno::Sequence< css::beans::NamedValue > GetObjectPropsByMediaType(const OUString &aMediaType)
css::uno::Sequence< css::beans::NamedValue > GetObjPropsFromConfigEntry(const css::uno::Sequence< sal_Int8 > &aClassID, const css::uno::Reference< css::container::XNameAccess > &xObjectProps)
css::uno::Reference< css::container::XNameAccess > m_xFilterFactory
css::uno::Reference< css::container::XNameAccess > m_xObjectConfig
css::uno::Reference< css::lang::XMultiServiceFactory > m_xConfigProvider
sal_Int32 const nLength
css::uno::Reference< css::container::XNameAccess > m_xMediaTypeConfig
SfxFilterFlags
const uno::Reference< uno::XComponentContext > m_xContext