1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: urlparameter.cxx,v $
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_xmlhelp.hxx"
34 #define WORKAROUND_98119
36 #ifdef WORKAROUND_98119
37 #include "bufferedinputstream.hxx"
41 #ifndef _VOS_DIAGNOSE_HXX_
42 #include <vos/diagnose.hxx>
44 #include <osl/thread.h>
45 #include <rtl/memory.h>
46 #include <osl/file.hxx>
47 #include <cppuhelper/weak.hxx>
48 #include <cppuhelper/queryinterface.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <rtl/uri.hxx>
51 #include <rtl/ustrbuf.hxx>
52 #include <libxslt/xslt.h>
53 #include <libxslt/transform.h>
54 #include <libxslt/xsltutils.h>
56 #include <com/sun/star/io/XActiveDataSink.hpp>
57 #include <com/sun/star/io/XInputStream.hpp>
58 #include <com/sun/star/io/XSeekable.hpp>
59 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
60 #include <com/sun/star/ucb/OpenMode.hpp>
61 #include <com/sun/star/ucb/XCommandProcessor.hpp>
62 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
63 #include <com/sun/star/ucb/XContentIdentifier.hpp>
64 #include <com/sun/star/ucb/XContentProvider.hpp>
65 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
66 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
67 #include <com/sun/star/beans/XPropertySet.hpp>
69 #include "urlparameter.hxx"
70 #include "databases.hxx"
74 inline bool ascii_isDigit( sal_Unicode ch
)
76 return ((ch
>= 0x0030) && (ch
<= 0x0039));
79 inline bool ascii_isLetter( sal_Unicode ch
)
81 return ( ( (ch
>= 0x0041) && (ch
<= 0x005A) ) ||
82 ( (ch
>= 0x0061) && (ch
<= 0x007A) ) );
85 inline bool isLetterOrDigit( sal_Unicode ch
)
87 return ascii_isLetter( ch
) || ascii_isDigit( ch
);
93 using namespace com::sun::star::io
;
94 using namespace com::sun::star::uno
;
95 using namespace com::sun::star::lang
;
96 using namespace com::sun::star::ucb
;
97 using namespace com::sun::star::beans
;
98 using namespace com::sun::star::container
;
99 using namespace berkeleydbproxy
;
100 using namespace chelp
;
103 URLParameter::URLParameter( const rtl::OUString
& aURL
,
104 Databases
* pDatabases
)
105 throw( com::sun::star::ucb::IllegalIdentifierException
)
106 : m_pDatabases( pDatabases
),
114 bool URLParameter::isErrorDocument()
116 bool bErrorDoc
= false;
120 Reference
< XHierarchicalNameAccess
> xNA
=
121 m_pDatabases
->findJarFileForPath( get_jar(), get_language(), get_path() );
122 bErrorDoc
= !xNA
.is();
129 rtl::OString
URLParameter::getByName( const char* par
)
133 if( strcmp( par
,"Program" ) == 0 )
135 else if( strcmp( par
,"Database" ) == 0 )
137 else if( strcmp( par
,"DatabasePar" ) == 0 )
139 else if( strcmp( par
,"Id" ) == 0 )
141 else if( strcmp( par
,"Path" ) == 0 )
143 else if( strcmp( par
,"Language" ) == 0 )
144 val
= get_language();
145 else if( strcmp( par
,"System" ) == 0 )
147 else if( strcmp( par
,"HelpPrefix" ) == 0 )
150 return rtl::OString( val
.getStr(),val
.getLength(),RTL_TEXTENCODING_UTF8
);
154 rtl::OUString
URLParameter::get_id()
156 if( m_aId
.compareToAscii("start") == 0 )
158 StaticModuleInformation
* inf
=
159 m_pDatabases
->getStaticInformationForModule( get_module(),
162 m_aId
= inf
->get_id();
170 rtl::OUString
URLParameter::get_tag()
173 return get_the_tag();
179 rtl::OUString
URLParameter::get_title()
182 return get_the_title();
183 else if( m_aModule
.compareToAscii("") != 0 )
185 StaticModuleInformation
* inf
=
186 m_pDatabases
->getStaticInformationForModule( get_module(),
189 m_aTitle
= inf
->get_title();
191 else // This must be the root
192 m_aTitle
= rtl::OUString::createFromAscii("root");
198 rtl::OUString
URLParameter::get_language()
200 if( m_aLanguage
.getLength() == 0 )
201 return m_aDefaultLanguage
;
207 rtl::OUString
URLParameter::get_program()
209 if( ! m_aProgram
.getLength() )
211 StaticModuleInformation
* inf
=
212 m_pDatabases
->getStaticInformationForModule( get_module(),
215 m_aProgram
= inf
->get_program();
221 void URLParameter::init( bool bDefaultLanguageIsInitialized
)
223 (void)bDefaultLanguageIsInitialized
;
225 m_bBerkeleyRead
= false;
228 m_nHitCount
= 100; // The default maximum hitcount
232 rtl::OUString
URLParameter::get_the_tag()
235 if( ! m_bBerkeleyRead
)
238 m_bBerkeleyRead
= true;
243 return rtl::OUString();
248 rtl::OUString
URLParameter::get_the_path()
251 if( ! m_bBerkeleyRead
)
253 m_bBerkeleyRead
= true;
263 rtl::OUString
URLParameter::get_the_title()
266 if( ! m_bBerkeleyRead
)
268 m_bBerkeleyRead
= true;
273 return rtl::OUString();
277 rtl::OUString
URLParameter::get_the_jar()
280 if( ! m_bBerkeleyRead
)
282 m_bBerkeleyRead
= true;
287 return get_module() + rtl::OUString::createFromAscii(".jar");
293 void URLParameter::readBerkeley()
295 static rtl::OUString
aQuestionMark( rtl::OUString::createFromAscii( "?" ) );
297 if( get_id().compareToAscii("") == 0 )
300 rtl::OUString aModule
= get_module();
301 rtl::OUString aLanguage
= get_language();
303 DataBaseIterator
aDbIt( *m_pDatabases
, aModule
, aLanguage
, false );
304 bool bSuccess
= false;
307 const sal_Char
* pData
= NULL
;
311 rtl::OUString aExtensionPath
;
314 Db
* db
= aDbIt
.nextDb( &aExtensionPath
);
318 rtl::OString
keyStr( m_aId
.getStr(),m_aId
.getLength(),RTL_TEXTENCODING_UTF8
);
320 DBHelp
* pDBHelp
= db
->getDBHelp();
321 if( pDBHelp
!= NULL
)
323 bSuccess
= pDBHelp
->getValueForKey( keyStr
, aDBData
);
326 nSize
= aDBData
.getSize();
327 pData
= aDBData
.getData();
333 Dbt
key( static_cast< void* >( const_cast< sal_Char
* >( keyStr
.getStr() ) ),
334 keyStr
.getLength() );
335 int err
= db
->get( 0,&key
,&data
,0 );
339 nSize
= data
.get_size();
340 pData
= static_cast<sal_Char
*>( data
.get_data() );
348 DbtToStringConverter
converter( pData
, nSize
);
349 m_aTitle
= converter
.getTitle();
350 m_pDatabases
->replaceName( m_aTitle
);
351 m_aPath
= converter
.getFile();
352 m_aJar
= converter
.getDatabase();
353 if( aExtensionPath
.getLength() > 0 )
355 rtl::OUStringBuffer aExtendedJarStrBuf
;
356 aExtendedJarStrBuf
.append( aQuestionMark
);
357 aExtendedJarStrBuf
.append( aExtensionPath
);
358 aExtendedJarStrBuf
.append( aQuestionMark
);
359 aExtendedJarStrBuf
.append( m_aJar
);
360 m_aJar
= aExtendedJarStrBuf
.makeStringAndClear();
362 m_aTag
= converter
.getHash();
368 // Class encapsulating the transformation of the XInputStream to XHTML
371 class InputStreamTransformer
372 : public OWeakObject
,
378 InputStreamTransformer( URLParameter
* urlParam
,
379 Databases
* pDatatabases
,
380 bool isRoot
= false );
382 ~InputStreamTransformer();
384 virtual Any SAL_CALL
queryInterface( const Type
& rType
) throw( RuntimeException
);
385 virtual void SAL_CALL
acquire( void ) throw();
386 virtual void SAL_CALL
release( void ) throw();
388 virtual sal_Int32 SAL_CALL
readBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nBytesToRead
)
389 throw( NotConnectedException
,
390 BufferSizeExceededException
,
394 virtual sal_Int32 SAL_CALL
readSomeBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nMaxBytesToRead
)
395 throw( NotConnectedException
,
396 BufferSizeExceededException
,
400 virtual void SAL_CALL
skipBytes( sal_Int32 nBytesToSkip
) throw( NotConnectedException
,
401 BufferSizeExceededException
,
405 virtual sal_Int32 SAL_CALL
available( void ) throw( NotConnectedException
,
409 virtual void SAL_CALL
closeInput( void ) throw( NotConnectedException
,
413 virtual void SAL_CALL
seek( sal_Int64 location
) throw( IllegalArgumentException
,
417 virtual sal_Int64 SAL_CALL
getPosition( void ) throw( IOException
,RuntimeException
);
419 virtual sal_Int64 SAL_CALL
getLength( void ) throw( IOException
,RuntimeException
);
421 void addToBuffer( const char* buffer
,int len
);
423 sal_Int8
* getData() const { return (sal_Int8
*) buffer
; }
425 sal_Int32
getLen() const { return sal_Int32( len
); }
437 void URLParameter::open( const Reference
< XMultiServiceFactory
>& rxSMgr
,
438 const Command
& aCommand
,
440 const Reference
< XCommandEnvironment
>& Environment
,
441 const Reference
< XOutputStream
>& xDataSink
)
448 if( ! xDataSink
.is() )
453 Reference
< XInputStream
> xStream
;
454 Reference
< XHierarchicalNameAccess
> xNA
=
455 m_pDatabases
->jarFile( rtl::OUString::createFromAscii( "picture.jar" ),
458 rtl::OUString path
= get_path();
463 Any aEntry
= xNA
->getByHierarchicalName( path
);
464 Reference
< XActiveDataSink
> xSink
;
465 if( ( aEntry
>>= xSink
) && xSink
.is() )
466 xStream
= xSink
->getInputStream();
468 catch ( NoSuchElementException
& )
475 Sequence
< sal_Int8
> aSeq( 4096 );
480 ret
= xStream
->readBytes( aSeq
,4096 );
481 xDataSink
->writeBytes( aSeq
);
485 catch( const Exception
& )
494 // a standard document or else an active help text, plug in the new input stream
495 InputStreamTransformer
* p
= new InputStreamTransformer( this,m_pDatabases
,isRoot() );
498 xDataSink
->writeBytes( Sequence
< sal_Int8
>( p
->getData(),p
->getLen() ) );
500 catch( const Exception
& )
505 xDataSink
->closeOutput();
510 void URLParameter::open( const Reference
< XMultiServiceFactory
>& rxSMgr
,
511 const Command
& aCommand
,
513 const Reference
< XCommandEnvironment
>& Environment
,
514 const Reference
< XActiveDataSink
>& xDataSink
)
523 Reference
< XInputStream
> xStream
;
524 Reference
< XHierarchicalNameAccess
> xNA
=
525 m_pDatabases
->jarFile( rtl::OUString::createFromAscii( "picture.jar" ),
528 rtl::OUString path
= get_path();
533 Any aEntry
= xNA
->getByHierarchicalName( path
);
534 Reference
< XActiveDataSink
> xSink
;
535 if( ( aEntry
>>= xSink
) && xSink
.is() )
536 xStream
= xSink
->getInputStream();
538 catch ( NoSuchElementException
& )
542 #ifdef WORKAROUND_98119
543 xDataSink
->setInputStream( turnToSeekable(xStream
) );
545 xDataSink
->setInputStream( xStream
);
549 // a standard document or else an active help text, plug in the new input stream
550 xDataSink
->setInputStream( new InputStreamTransformer( this,m_pDatabases
,isRoot() ) );
554 // #include <stdio.h>
556 void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException
)
558 // fprintf(stdout,"url send to xmlhelp: %s\n",(rtl::OUStringToOString(m_aURL,RTL_TEXTENCODING_UTF8).getStr()));
561 sal_Int32 lstIdx
= m_aExpr
.lastIndexOf( sal_Unicode( '#' ) );
563 m_aExpr
= m_aExpr
.copy( 0,lstIdx
);
566 ! name( module() ) ||
568 ! m_aLanguage
.getLength() ||
569 ! m_aSystem
.getLength() )
570 throw com::sun::star::ucb::IllegalIdentifierException();
574 bool URLParameter::scheme()
576 // Correct extension help links as sometimes the
577 // module is missing resulting in a misformed URL
578 if( m_aExpr
.compareToAscii( "vnd.sun.star.help:///", 21 ) == 0 )
580 sal_Int32 nLen
= m_aExpr
.getLength();
581 rtl::OUString aLastStr
= m_aExpr
.copy( nLen
- 6 );
582 if( aLastStr
.compareToAscii( "DbPAR=" ) == 0 )
584 rtl::OUString aNewExpr
= m_aExpr
.copy( 0, 20 );
585 rtl::OUString aSharedStr
= rtl::OUString::createFromAscii( "shared" );
586 aNewExpr
+= aSharedStr
;
587 aNewExpr
+= m_aExpr
.copy( 20 );
588 aNewExpr
+= aSharedStr
;
593 for( sal_Int32 nPrefixLen
= 20 ; nPrefixLen
>= 18 ; --nPrefixLen
)
595 if( m_aExpr
.compareToAscii( "vnd.sun.star.help://", nPrefixLen
) == 0 )
597 m_aExpr
= m_aExpr
.copy( nPrefixLen
);
605 bool URLParameter::module()
607 sal_Int32 idx
= 0,length
= m_aExpr
.getLength();
609 while( idx
< length
&& isLetterOrDigit( (m_aExpr
.getStr())[idx
] ) )
614 m_aModule
= m_aExpr
.copy( 0,idx
);
615 m_aExpr
= m_aExpr
.copy( idx
);
624 bool URLParameter::name( bool modulePresent
)
626 // if modulepresent, a name may be present, but must not
628 sal_Int32 length
= m_aExpr
.getLength();
630 if( length
!= 0 && (m_aExpr
.getStr())[0] == sal_Unicode( '/' ) )
633 while( idx
< length
&& (m_aExpr
.getStr())[idx
] != '?' )
634 // ( isLetterOrDigit( (m_aExpr.getStr())[idx] )
635 // || (m_aExpr.getStr())[idx] == '/'
636 // || (m_aExpr.getStr())[idx] == '.' ))
639 if( idx
!= 1 && ! modulePresent
)
643 m_aId
= m_aExpr
.copy( 1,idx
-1 );
644 m_aExpr
= m_aExpr
.copy( idx
);
648 // fprintf(stdout,"id %s\n",(rtl::OUStringToOString(m_aId,RTL_TEXTENCODING_UTF8).getStr()));
653 bool URLParameter::query()
655 rtl::OUString query_
;
657 if( ! m_aExpr
.getLength() )
659 else if( (m_aExpr
.getStr())[0] == sal_Unicode( '?' ) )
660 query_
= m_aExpr
.copy( 1 ).trim();
666 sal_Int32 delimIdx
,equalIdx
;
667 rtl::OUString parameter
,value
;
669 while( query_
.getLength() != 0 )
671 delimIdx
= query_
.indexOf( sal_Unicode( '&' ) );
672 equalIdx
= query_
.indexOf( sal_Unicode( '=' ) );
673 parameter
= query_
.copy( 0,equalIdx
).trim();
676 value
= query_
.copy( equalIdx
+ 1 ).trim();
677 query_
= rtl::OUString();
681 value
= query_
.copy( equalIdx
+1,delimIdx
- equalIdx
- 1 ).trim();
682 query_
= query_
.copy( delimIdx
+1 ).trim();
685 if( parameter
.compareToAscii( "Language" ) == 0 )
687 else if( parameter
.compareToAscii( "Device" ) == 0 )
689 else if( parameter
.compareToAscii( "Program" ) == 0 )
691 else if( parameter
.compareToAscii( "Eid" ) == 0 )
693 else if( parameter
.compareToAscii( "UseDB" ) == 0 )
694 m_bUseDB
= ! ( value
.compareToAscii("no") == 0 );
695 else if( parameter
.compareToAscii( "DbPAR" ) == 0 )
697 else if( parameter
.compareToAscii( "Query" ) == 0 )
699 if( ! m_aQuery
.getLength() )
702 m_aQuery
+= ( rtl::OUString::createFromAscii( " " ) + value
);
704 else if( parameter
.compareToAscii( "Scope" ) == 0 )
706 else if( parameter
.compareToAscii( "System" ) == 0 )
708 else if( parameter
.compareToAscii( "HelpPrefix" ) == 0 )
709 m_aPrefix
= rtl::Uri::decode(
711 rtl_UriDecodeWithCharset
,
712 RTL_TEXTENCODING_UTF8
);
713 else if( parameter
.compareToAscii( "HitCount" ) == 0 )
714 m_nHitCount
= value
.toInt32();
715 else if( parameter
.compareToAscii( "Active" ) == 0 )
726 UserData( InputStreamTransformer
* pTransformer
,
727 URLParameter
* pInitial
,
728 Databases
* pDatabases
)
729 : m_pTransformer( pTransformer
),
730 m_pDatabases( pDatabases
),
731 m_pInitial( pInitial
)
735 InputStreamTransformer
* m_pTransformer
;
736 Databases
* m_pDatabases
;
737 URLParameter
* m_pInitial
;
740 UserData
*ugblData
= 0;
745 fileMatch(const char * URI
) {
746 if ((URI
!= NULL
) && !strncmp(URI
, "file:/", 6))
752 zipMatch(const char * URI
) {
753 if ((URI
!= NULL
) && !strncmp(URI
, "vnd.sun.star.zip:/", 18))
759 helpMatch(const char * URI
) {
760 if ((URI
!= NULL
) && !strncmp(URI
, "vnd.sun.star.help:/", 19))
766 fileOpen(const char *URI
) {
767 osl::File
*pRet
= new osl::File(rtl::OUString(URI
, strlen(URI
), RTL_TEXTENCODING_UTF8
));
768 pRet
->open(OpenFlag_Read
);
773 zipOpen(const char * /*URI*/) {
774 rtl::OUString language
,jar
,path
;
776 if( ugblData
->m_pInitial
->get_eid().getLength() )
777 return (void*)(new Reference
< XHierarchicalNameAccess
>);
780 jar
= ugblData
->m_pInitial
->get_jar();
781 language
= ugblData
->m_pInitial
->get_language();
782 path
= ugblData
->m_pInitial
->get_path();
785 Reference
< XHierarchicalNameAccess
> xNA
=
786 ugblData
->m_pDatabases
->findJarFileForPath( jar
, language
, path
);
788 Reference
< XInputStream
> xInputStream
;
794 Any aEntry
= xNA
->getByHierarchicalName( path
);
795 Reference
< XActiveDataSink
> xSink
;
796 if( ( aEntry
>>= xSink
) && xSink
.is() )
797 xInputStream
= xSink
->getInputStream();
799 catch ( NoSuchElementException
& )
804 if( xInputStream
.is() )
806 return new Reference
<XInputStream
>(xInputStream
);
812 helpOpen(const char * URI
) {
813 rtl::OUString language
,jar
,path
;
815 URLParameter
urlpar( rtl::OUString::createFromAscii( URI
),
816 ugblData
->m_pDatabases
);
818 jar
= urlpar
.get_jar();
819 language
= urlpar
.get_language();
820 path
= urlpar
.get_path();
822 Reference
< XHierarchicalNameAccess
> xNA
=
823 ugblData
->m_pDatabases
->findJarFileForPath( jar
, language
, path
);
825 Reference
< XInputStream
> xInputStream
;
831 Any aEntry
= xNA
->getByHierarchicalName( path
);
832 Reference
< XActiveDataSink
> xSink
;
833 if( ( aEntry
>>= xSink
) && xSink
.is() )
834 xInputStream
= xSink
->getInputStream();
836 catch ( NoSuchElementException
& )
841 if( xInputStream
.is() )
842 return new Reference
<XInputStream
>(xInputStream
);
847 helpRead(void * context
, char * buffer
, int len
) {
848 Reference
< XInputStream
> *pRef
= (Reference
< XInputStream
>*)context
;
850 Sequence
< sal_Int8
> aSeq
;
851 len
= (*pRef
)->readBytes( aSeq
,len
);
852 memcpy(buffer
, aSeq
.getConstArray(), len
);
858 zipRead(void * context
, char * buffer
, int len
) {
859 if( ugblData
->m_pInitial
->get_eid().getLength() )
861 ugblData
->m_pDatabases
->popupDocument( ugblData
->m_pInitial
,&buffer
,&len
);
865 return helpRead(context
, buffer
, len
);
869 fileRead(void * context
, char * buffer
, int len
) {
871 osl::File
*pFile
= (osl::File
*)context
;
874 sal_uInt64 uRead
= 0;
875 if (osl::FileBase::E_None
== pFile
->read(buffer
, len
, uRead
))
876 nRead
= static_cast<int>(uRead
);
882 uriClose(void * context
) {
883 Reference
< XInputStream
> *pRef
= (Reference
< XInputStream
>*)context
;
889 fileClose(void * context
) {
890 osl::File
*pFile
= (osl::File
*)context
;
902 // For debugging only
903 extern "C" void StructuredXMLErrorFunction(void *userData, xmlErrorPtr error)
908 // Reset error handler
909 xmlSetStructuredErrorFunc( NULL, NULL );
913 InputStreamTransformer::InputStreamTransformer( URLParameter
* urlParam
,
914 Databases
* pDatabases
,
918 buffer( new char[1] ) // Initializing with one element to avoid gcc compiler warning
923 pDatabases
->cascadingStylesheet( urlParam
->get_language(),
927 else if( urlParam
->isActive() )
930 pDatabases
->setActiveText( urlParam
->get_module(),
931 urlParam
->get_language(),
938 UserData
userData( this,urlParam
,pDatabases
);
940 // Uses the implementation detail, that rtl::OString::getStr returns a zero terminated character-array
942 const char* parameter
[47];
943 rtl::OString parString
[46];
946 parString
[last
++] = "Program";
947 rtl::OString
aPureProgramm( urlParam
->getByName( "Program" ) );
948 parString
[last
++] = rtl::OString('\'') + aPureProgramm
+ rtl::OString('\'');
949 parString
[last
++] = "Database";
950 parString
[last
++] = rtl::OString('\'') + urlParam
->getByName( "DatabasePar" ) + rtl::OString('\'');
951 parString
[last
++] = "Id";
952 parString
[last
++] = rtl::OString('\'') + urlParam
->getByName( "Id" ) + rtl::OString('\'');
953 parString
[last
++] = "Path";
954 rtl::OString
aPath( urlParam
->getByName( "Path" ) );
955 parString
[last
++] = rtl::OString('\'') + aPath
+ rtl::OString('\'');
957 rtl::OString aPureLanguage
= urlParam
->getByName( "Language" );
958 parString
[last
++] = "Language";
959 parString
[last
++] = rtl::OString('\'') + aPureLanguage
+ rtl::OString('\'');
960 parString
[last
++] = "System";
961 parString
[last
++] = rtl::OString('\'') + urlParam
->getByName( "System" ) + rtl::OString('\'');
962 parString
[last
++] = "productname";
963 parString
[last
++] = rtl::OString('\'') + rtl::OString(
964 pDatabases
->getProductName().getStr(),
965 pDatabases
->getProductName().getLength(),
966 RTL_TEXTENCODING_UTF8
) + rtl::OString('\'');
967 parString
[last
++] = "productversion";
968 parString
[last
++] = rtl::OString('\'') +
969 rtl::OString( pDatabases
->getProductVersion().getStr(),
970 pDatabases
->getProductVersion().getLength(),
971 RTL_TEXTENCODING_UTF8
) + rtl::OString('\'');
973 parString
[last
++] = "imgrepos";
974 parString
[last
++] = rtl::OString('\'') + pDatabases
->getImagesZipFileURL() + rtl::OString('\'');
975 parString
[last
++] = "hp";
976 parString
[last
++] = rtl::OString('\'') + urlParam
->getByName( "HelpPrefix" ) + rtl::OString('\'');
978 if( parString
[last
-1].getLength() )
980 parString
[last
++] = "sm";
981 parString
[last
++] = "'vnd.sun.star.help%3A%2F%2F'";
982 parString
[last
++] = "qm";
983 parString
[last
++] = "'%3F'";
984 parString
[last
++] = "es";
985 parString
[last
++] = "'%3D'";
986 parString
[last
++] = "am";
987 parString
[last
++] = "'%26'";
988 parString
[last
++] = "cl";
989 parString
[last
++] = "'%3A'";
990 parString
[last
++] = "sl";
991 parString
[last
++] = "'%2F'";
992 parString
[last
++] = "hm";
993 parString
[last
++] = "'%23'";
994 parString
[last
++] = "cs";
995 parString
[last
++] = "'css'";
997 parString
[last
++] = "vendorname";
998 parString
[last
++] = rtl::OString('\'') +
999 rtl::OString( pDatabases
->getVendorName().getStr(),
1000 pDatabases
->getVendorName().getLength(),
1001 RTL_TEXTENCODING_UTF8
) + rtl::OString('\'');
1002 parString
[last
++] = "vendorversion";
1003 parString
[last
++] = rtl::OString('\'') +
1004 rtl::OString( pDatabases
->getVendorVersion().getStr(),
1005 pDatabases
->getVendorVersion().getLength(),
1006 RTL_TEXTENCODING_UTF8
) + rtl::OString('\'');
1007 parString
[last
++] = "vendorshort";
1008 parString
[last
++] = rtl::OString('\'') +
1009 rtl::OString( pDatabases
->getVendorShort().getStr(),
1010 pDatabases
->getVendorShort().getLength(),
1011 RTL_TEXTENCODING_UTF8
) + rtl::OString('\'');
1014 // Do we need to add extension path?
1015 ::rtl::OUString aExtensionPath
;
1016 rtl::OUString aJar
= urlParam
->get_jar();
1018 bool bAddExtensionPath
= false;
1019 sal_Int32 nQuestionMark1
= aJar
.indexOf( sal_Unicode('?') );
1020 sal_Int32 nQuestionMark2
= aJar
.lastIndexOf( sal_Unicode('?') );
1021 if( nQuestionMark1
!= -1 && nQuestionMark2
!= -1 && nQuestionMark1
!= nQuestionMark2
)
1023 aExtensionPath
= aJar
.copy( nQuestionMark1
+ 1, nQuestionMark2
- nQuestionMark1
- 1 );
1024 bAddExtensionPath
= true;
1028 // Path not yet specified, search directly
1029 Reference
< XHierarchicalNameAccess
> xNA
= pDatabases
->findJarFileForPath
1030 ( aJar
, urlParam
->get_language(), urlParam
->get_path(), &aExtensionPath
);
1031 if( xNA
.is() && aExtensionPath
.getLength() )
1032 bAddExtensionPath
= true;
1035 if( bAddExtensionPath
)
1037 Reference
< XMultiServiceFactory
> xFactory
= comphelper::getProcessServiceFactory();
1038 Reference
< XPropertySet
> xProps( xFactory
, UNO_QUERY
);
1039 OSL_ASSERT( xProps
.is() );
1040 Reference
< XComponentContext
> xContext
;
1043 xProps
->getPropertyValue(
1044 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext
;
1046 if( !xContext
.is() )
1048 throw RuntimeException(
1049 ::rtl::OUString::createFromAscii( "InputStreamTransformer::InputStreamTransformer(), no XComponentContext" ),
1050 Reference
< XInterface
>() );
1053 rtl::OUString aOUExpandedExtensionPath
= Databases::expandURL( aExtensionPath
, xContext
);
1054 rtl::OString aExpandedExtensionPath
= rtl::OUStringToOString( aOUExpandedExtensionPath
, osl_getThreadTextEncoding() );
1056 parString
[last
++] = "ExtensionPath";
1057 parString
[last
++] = rtl::OString('\'') + aExpandedExtensionPath
+ rtl::OString('\'');
1060 rtl::OString aPureExtensionId
;
1061 sal_Int32 iSlash
= aPath
.indexOf( '/' );
1063 aPureExtensionId
= aPath
.copy( 0, iSlash
);
1065 parString
[last
++] = "ExtensionId";
1066 parString
[last
++] = rtl::OString('\'') + aPureExtensionId
+ rtl::OString('\'');
1069 for( int i
= 0; i
< last
; ++i
)
1070 parameter
[i
] = parString
[i
].getStr();
1071 parameter
[last
] = 0;
1073 rtl::OUString xslURL
= pDatabases
->getInstallPathAsURL();
1075 rtl::OString
xslURLascii(
1078 RTL_TEXTENCODING_UTF8
);
1079 xslURLascii
+= "main_transform.xsl";
1081 ugblData
= &userData
;
1083 xmlRegisterInputCallbacks(zipMatch
, zipOpen
, zipRead
, uriClose
);
1084 xmlRegisterInputCallbacks(helpMatch
, helpOpen
, helpRead
, uriClose
);
1085 xmlRegisterInputCallbacks(fileMatch
, fileOpen
, fileRead
, fileClose
);
1086 //xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction );
1088 xsltStylesheetPtr cur
=
1089 xsltParseStylesheetFile((const xmlChar
*)xslURLascii
.getStr());
1091 xmlDocPtr doc
= xmlParseFile("vnd.sun.star.zip:/");
1093 xmlDocPtr res
= xsltApplyStylesheet(cur
, doc
, parameter
);
1096 xmlChar
*doc_txt_ptr
=0;
1098 xsltSaveResultToString(&doc_txt_ptr
, &doc_txt_len
, res
, cur
);
1099 addToBuffer((const char*)doc_txt_ptr
, doc_txt_len
);
1100 xmlFree(doc_txt_ptr
);
1102 xmlPopInputCallbacks(); //filePatch
1103 xmlPopInputCallbacks(); //helpPatch
1104 xmlPopInputCallbacks(); //zipMatch
1107 xsltFreeStylesheet(cur
);
1112 InputStreamTransformer::~InputStreamTransformer()
1118 Any SAL_CALL
InputStreamTransformer::queryInterface( const Type
& rType
) throw( RuntimeException
)
1120 Any aRet
= ::cppu::queryInterface( rType
,
1121 SAL_STATIC_CAST( XInputStream
*,this ),
1122 SAL_STATIC_CAST( XSeekable
*,this ) );
1124 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
1129 void SAL_CALL
InputStreamTransformer::acquire( void ) throw()
1131 OWeakObject::acquire();
1136 void SAL_CALL
InputStreamTransformer::release( void ) throw()
1138 OWeakObject::release();
1143 sal_Int32 SAL_CALL
InputStreamTransformer::readBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nBytesToRead
)
1144 throw( NotConnectedException
,
1145 BufferSizeExceededException
,
1149 osl::MutexGuard
aGuard( m_aMutex
);
1151 int curr
,available_
= len
-pos
;
1152 if( nBytesToRead
<= available_
)
1153 curr
= nBytesToRead
;
1157 if( 0 <= curr
&& aData
.getLength() < curr
)
1158 aData
.realloc( curr
);
1160 for( int k
= 0; k
< curr
; ++k
)
1161 aData
[k
] = buffer
[pos
++];
1163 return curr
> 0 ? curr
: 0;
1167 sal_Int32 SAL_CALL
InputStreamTransformer::readSomeBytes( Sequence
< sal_Int8
>& aData
,sal_Int32 nMaxBytesToRead
)
1168 throw( NotConnectedException
,
1169 BufferSizeExceededException
,
1173 return readBytes( aData
,nMaxBytesToRead
);
1178 void SAL_CALL
InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip
) throw( NotConnectedException
,
1179 BufferSizeExceededException
,
1183 osl::MutexGuard
aGuard( m_aMutex
);
1184 while( nBytesToSkip
-- ) ++pos
;
1189 sal_Int32 SAL_CALL
InputStreamTransformer::available( void ) throw( NotConnectedException
,
1193 osl::MutexGuard
aGuard( m_aMutex
);
1194 return len
-pos
> 0 ? len
- pos
: 0 ;
1199 void SAL_CALL
InputStreamTransformer::closeInput( void ) throw( NotConnectedException
,
1207 void SAL_CALL
InputStreamTransformer::seek( sal_Int64 location
) throw( IllegalArgumentException
,
1211 osl::MutexGuard
aGuard( m_aMutex
);
1213 throw IllegalArgumentException();
1215 pos
= sal::static_int_cast
<sal_Int32
>( location
);
1223 sal_Int64 SAL_CALL
InputStreamTransformer::getPosition( void ) throw( IOException
,
1226 osl::MutexGuard
aGuard( m_aMutex
);
1227 return sal_Int64( pos
);
1232 sal_Int64 SAL_CALL
InputStreamTransformer::getLength( void ) throw( IOException
,RuntimeException
)
1234 osl::MutexGuard
aGuard( m_aMutex
);
1240 void InputStreamTransformer::addToBuffer( const char* buffer_
,int len_
)
1242 osl::MutexGuard
aGuard( m_aMutex
);
1245 buffer
= new char[ len
+len_
];
1246 rtl_copyMemory( (void*)(buffer
),(void*)(tmp
),sal_uInt32( len
) );
1247 rtl_copyMemory( (void*)(buffer
+len
),(void*)(buffer_
),sal_uInt32( len_
) );