diff options
Diffstat (limited to 'xmlhelp/source/cxxhelp')
41 files changed, 11082 insertions, 0 deletions
diff --git a/xmlhelp/source/cxxhelp/inc/db/EntryProcessor.hxx b/xmlhelp/source/cxxhelp/inc/db/EntryProcessor.hxx new file mode 100644 index 000000000000..c50b7b50e8c7 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/db/EntryProcessor.hxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_DB_ENTRYPROCESSOR_HXX_ +#define _XMLSEARCH_DB_ENTRYPROCESSOR_HXX_ + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring> +#endif + +namespace xmlsearch { + + namespace db { + + + class EntryProcessor + { + public: + + virtual ~EntryProcessor() = 0; + virtual void processEntry( rtl::OUString string,sal_Int32 id ) = 0; + }; + + + } +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/excep/XmlSearchExceptions.hxx b/xmlhelp/source/cxxhelp/inc/excep/XmlSearchExceptions.hxx new file mode 100644 index 000000000000..47468c8547ad --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/excep/XmlSearchExceptions.hxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_EXCEP_XMLSEARCHEXCEPTIONS_HXX_ +#define _XMLSEARCH_EXCEP_XMLSEARCHEXCEPTIONS_HXX_ + +#include <rtl/ustring.hxx> + + +namespace xmlsearch { + + namespace excep { + + + class XmlSearchException + { + public: + + XmlSearchException( const rtl::OUString& message ) + : _message( message ) + { + } + + rtl::OUString getMessage() const + { + return _message; + } + + + private: + + rtl::OUString _message; + }; + + + class IOException + : public virtual XmlSearchException + { + public: + + IOException( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + + class NoFactoryException + : public virtual XmlSearchException + { + public: + NoFactoryException( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + + class NoSuchBlock + : public virtual XmlSearchException + { + public: + NoSuchBlock( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + + class IllegalIndexException + : public virtual XmlSearchException + { + public: + IllegalIndexException( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + } +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/qe/DocGenerator.hxx b/xmlhelp/source/cxxhelp/inc/qe/DocGenerator.hxx new file mode 100644 index 000000000000..3fc584402fcf --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/DocGenerator.hxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_QE_DOCGENERATOR_HXX_ +#define _XMLSEARCH_QE_DOCGENERATOR_HXX_ + +#include <rtl/ref.hxx> +#ifndef _RTL_USTRING_HXX__ +#include <rtl/ustring.hxx> +#endif +#include <excep/XmlSearchExceptions.hxx> +#include <util/CompressorIterator.hxx> +#include <util/Decompressor.hxx> + + +namespace xmlsearch { + + namespace qe { + + + class Query; + + + class NonnegativeIntegerGenerator + { + public: + + static const sal_Int32 END; + + virtual ~NonnegativeIntegerGenerator() { }; + virtual sal_Int32 first() throw( xmlsearch::excep::XmlSearchException ) = 0; + virtual sal_Int32 next() throw( xmlsearch::excep::XmlSearchException ) = 0; + }; + + + class RoleFiller + { + public: + + static RoleFiller* STOP() { return &roleFiller_; } + + RoleFiller(); + + ~RoleFiller(); + + void acquire() { ++m_nRefcount; } + void release() { if( ! --m_nRefcount ) delete this; } + + private: + + static RoleFiller roleFiller_; + + sal_uInt32 m_nRefcount; + sal_uInt8 fixedRole_; + sal_Int16 filled_; + sal_Int32 begin_,end_,parentContext_,limit_; + + RoleFiller* next_; + std::vector< RoleFiller* > fillers_; + }; + + + class GeneratorHeap + { + public: + + GeneratorHeap() + : heapSize_( 0 ), + free_( 0 ) + { } + private: + + sal_Int32 heapSize_,free_; + }; + + + + } +} + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/qe/Query.hxx b/xmlhelp/source/cxxhelp/inc/qe/Query.hxx new file mode 100644 index 000000000000..41a1d168ea9f --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/Query.hxx @@ -0,0 +1,175 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_QE_QUERY_HXX_ +#define _XMLSEARCH_QE_QUERY_HXX_ + +#include <sal/types.h> +#include <rtl/memory.h> +#include <rtl/ustring.hxx> +#include <vector> + + +namespace xmlsearch { + + namespace qe { + + class Search; + class RoleFiller; + + class QueryHit + { + public: + + QueryHit( sal_Int32 nColumns,double penalty,sal_Int32 doc,sal_Int32 begin,sal_Int32 end ) + : doc_( doc ), + begin_( begin ), + end_( end ), + matchesL_( 2*nColumns ), + matches_( new sal_Int32[ 2*nColumns ] ), + penalty_( penalty ) + { + rtl_zeroMemory( matches_,sizeof( sal_Int32 ) * matchesL_ ); + } + + ~QueryHit() { delete[] matches_; } + + sal_Int32 getDocument() const { return doc_; } + + sal_Int32 countOfMatches() const { return matchesL_; } + + sal_Int32 getBegin() const { return begin_; } + + sal_Int32 getEnd() const { return end_; } + + double getPenalty() const { return penalty_; } + + bool betterThan( const QueryHit* o ) + { + if( penalty_ != o->penalty_ ) + return penalty_ < o->penalty_; + else if( begin_ != o->begin_ ) + return begin_ < o->begin_; + else if( end_ != o->end_ ) + return end_ < o->end_; + else + return false; + } + + bool worseThan( const QueryHit* o ) + { + if( penalty_ != o->penalty_ ) + return penalty_ > o->penalty_; + else if( begin_ != o->begin_ ) + return begin_ > o->begin_; + else if( end_ != o->end_ ) + return end_ > o->end_; + else + return false; + } + + bool worseThan( double penalty,sal_Int32 begin,sal_Int32 end ) + { + if( penalty_ != penalty ) + return penalty_ > penalty; + else if( begin_ != begin ) + return begin_ > begin; + else if( end_ != end ) + return end_ > end; + else + return false; + } + + bool compareTo( const QueryHit* o ) const + { + if( penalty_ != o->penalty_ ) + return penalty_ < o->penalty_; + else if( begin_ != o->begin_ ) + return begin_ < o->begin_; + else if( end_ != o->end_ ) + return end_ < o->end_; + else + return false; + } + + + private: + + sal_Int32 doc_,begin_,end_; + + sal_Int32 matchesL_; + sal_Int32 *matches_; // ...concept, word number, ... + + double penalty_; + + }; // end class QueryHit + + + + class QueryHitData + { + public: + + QueryHitData( double penalty,const rtl::OUString& document,sal_Int32 termsL, rtl::OUString* terms ) + : penalty_( penalty ), + document_( document ), + termsL_( termsL ), + terms_( terms ) { } + + ~QueryHitData() { delete[] terms_; } + + rtl::OUString getDocument() const { return document_; } + + double getPenalty() const { return penalty_; } + + + private: + + double penalty_; + + const rtl::OUString document_; + + sal_Int32 termsL_; + rtl::OUString* terms_; + + }; // end class QueryHitData + + + class PrefixTranslator + { + public: + + static PrefixTranslator* makePrefixTranslator( const rtl::OUString*,sal_Int32 ) + { + return 0; + } + }; + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/CompressorIterator.hxx b/xmlhelp/source/cxxhelp/inc/util/CompressorIterator.hxx new file mode 100644 index 000000000000..5695d3cdfc2b --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/CompressorIterator.hxx @@ -0,0 +1,49 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_UTIL_COMPRESSORITERATOR_HXX_ +#define _XMLSEARCH_UTIL_COMPRESSORITERATOR_HXX_ + + +namespace xmlsearch { + + namespace util { + + class CompressorIterator + { + public: + + virtual void value( sal_Int32 ) = 0; + + }; + + + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/ConceptList.hxx b/xmlhelp/source/cxxhelp/inc/util/ConceptList.hxx new file mode 100644 index 000000000000..c894ce0d8b13 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/ConceptList.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_UTIL_CONCEPTLIST_HXX_ +#define _XMLSEARCH_UTIL_CONCEPTLIST_HXX_ + +#include <excep/XmlSearchExceptions.hxx> +#include <qe/DocGenerator.hxx> +#include <util/Decompressor.hxx> +#include <util/CompressorIterator.hxx> + + +namespace xmlsearch { + + namespace util { + + + class CompressorIterator; + + + + class ConceptList + : public CompressorIterator, + public xmlsearch::qe::NonnegativeIntegerGenerator + { + public: + + ConceptList( sal_Int8* array,sal_Int32 arrl,sal_Int32 index ) + : k_( array[index] ), + value_( 0 ), + list_( arrl,array,index + 1 ) { } + + void value( sal_Int32 val ) { value_ += val; } + + private: + + sal_Int32 k_,value_; + ByteArrayDecompressor list_; + + }; + + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/Decompressor.hxx b/xmlhelp/source/cxxhelp/inc/util/Decompressor.hxx new file mode 100644 index 000000000000..ee77d4d8332e --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/Decompressor.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_UTIL_DECOMPRESSOR_HXX_ +#define _XMLSEARCH_UTIL_DECOMPRESSOR_HXX_ + +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <excep/XmlSearchExceptions.hxx> +#include <util/RandomAccessStream.hxx> + + +namespace xmlsearch { + + namespace util { + + + class CompressorIterator; + + + class Decompressor + { + public: + + Decompressor() + : toRead_( 0 ), + path_( 0 ) + { + } + + virtual ~Decompressor() { } + + virtual sal_Int32 getNextByte() = 0; + + virtual void initReading() + { + toRead_ = 0; + } + + private: + + static const sal_Int32 BitsInByte; + static const sal_Int32 NBits; + + sal_Int32 readByte_, toRead_, path_; + }; + + + + + class StreamDecompressor + : public Decompressor + { + public: + + StreamDecompressor( RandomAccessStream* in ) + : in_( in ) + { + } + + ~StreamDecompressor() { } + + + virtual sal_Int32 getNextByte(); + + private: + + RandomAccessStream* in_; + + }; + + + + class ByteArrayDecompressor + : public Decompressor + { + public: + + ByteArrayDecompressor( sal_Int32 arrayL,sal_Int8* array,sal_Int32 index ) + { + initReading(array,arrayL,index); + } + + + ~ByteArrayDecompressor() { } + + sal_Int32 bytesRead() + { + return index_ - index0_; + } + + + sal_Int32 getNextByte() throw( xmlsearch::excep::XmlSearchException ) + { + if( arrayL_ <= index_ ) + throw xmlsearch::excep::XmlSearchException( + rtl::OUString::createFromAscii( "ByteArrayDecompressor->getNextByte()" ) ); + return array_[index_++] & 0xFF; + } + + + private: + + sal_Int32 arrayL_; + sal_Int8 *array_; + + sal_Int32 index_,index0_; + + using xmlsearch::util::Decompressor::initReading; + void initReading( sal_Int8* array,sal_Int32 arrayL,sal_Int32 index ) + { + arrayL_ = arrayL; + array_ = array; + index_ = index0_ = index; + Decompressor::initReading(); + } + + }; + + + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/RandomAccessStream.hxx b/xmlhelp/source/cxxhelp/inc/util/RandomAccessStream.hxx new file mode 100644 index 000000000000..4598497672a4 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/RandomAccessStream.hxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLEARCH_UTIL_RANDOMACCESSSTREAM_HXX_ +#define _XMLEARCH_UTIL_RANDOMACCESSSTREAM_HXX_ + +#include <osl/file.hxx> + +namespace xmlsearch { + + namespace util { + + + class RandomAccessStream + { + public: + + virtual ~RandomAccessStream() { }; + + // The calle is responsible for allocating the buffer + virtual void seek( sal_Int32 ) = 0; + virtual sal_Int32 readBytes( sal_Int8*,sal_Int32 ) = 0; + virtual void writeBytes( sal_Int8*, sal_Int32 ) = 0; + virtual sal_Int32 length() = 0; + virtual void close() = 0; + + + protected: + + enum OPENFLAG { Read = OpenFlag_Read, + Write = OpenFlag_Write, + Create = OpenFlag_Create }; + + }; + + + } +} + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx new file mode 100644 index 000000000000..c0fe0e48ab08 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <rtl/memory.h> +#include "bufferedinputstream.hxx" + + +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::io; +using namespace chelp; + + +Reference<XInputStream> chelp::turnToSeekable(const Reference<XInputStream>& xInputStream) +{ + if( ! xInputStream.is() ) + return xInputStream; + + Reference<XSeekable> xSeekable(xInputStream,UNO_QUERY); + + if( xSeekable.is() ) + return xInputStream; + + return new BufferedInputStream(xInputStream); +} + + + +BufferedInputStream::BufferedInputStream(const Reference<XInputStream>& xInputStream) + : m_nBufferLocation(0), + m_nBufferSize(0), + m_pBuffer(new sal_Int8[1]) // Initialize with one to avoid gcc compiler warnings +{ + try + { + sal_Int32 num; + sal_Int8 *tmp; + Sequence< sal_Int8 > aData(4096); + do{ + num = xInputStream->readBytes(aData,4096); + if( num > 0 ) + { + tmp = m_pBuffer; + m_pBuffer = new sal_Int8[m_nBufferSize+num]; + rtl_copyMemory((void *)(m_pBuffer), + (void *)(tmp), + sal_uInt32(m_nBufferSize)); + rtl_copyMemory((void *)(m_pBuffer+m_nBufferSize), + (void *)(aData.getArray()), + sal_uInt32(num)); + m_nBufferSize += num; + delete[] tmp; + } + } while( num == 4096 ); + } + catch( const NotConnectedException&) + { + } + catch( const BufferSizeExceededException&) + { + } + catch( const IOException&) + { + } + catch( const RuntimeException&) + { + } + xInputStream->closeInput(); +} + + +BufferedInputStream::~BufferedInputStream() +{ + delete[] m_pBuffer; +} + + +Any SAL_CALL BufferedInputStream::queryInterface( const Type& rType ) throw( RuntimeException ) +{ + Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( XInputStream*,this ), + SAL_STATIC_CAST( XSeekable*,this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL BufferedInputStream::acquire( void ) throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL BufferedInputStream::release( void ) throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL BufferedInputStream::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if( 0 > nBytesToRead ) + throw BufferSizeExceededException(); + + if( m_nBufferLocation + nBytesToRead > m_nBufferSize ) + nBytesToRead = m_nBufferSize - m_nBufferLocation; + + if( aData.getLength() < nBytesToRead ) + aData.realloc(nBytesToRead); + + rtl_copyMemory((void*)(aData.getArray()), + (void*)(m_pBuffer+m_nBufferLocation), + nBytesToRead); + + return nBytesToRead; +} + + +sal_Int32 SAL_CALL BufferedInputStream::readSomeBytes( + Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + return readBytes(aData,nMaxBytesToRead); +} + + + +void SAL_CALL BufferedInputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + try + { + seek(m_nBufferLocation+nBytesToSkip); + } + catch( const IllegalArgumentException& ) + { + throw BufferSizeExceededException(); + } +} + + + +sal_Int32 SAL_CALL BufferedInputStream::available( void ) + throw( NotConnectedException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return m_nBufferSize-m_nBufferLocation; +} + + + +void SAL_CALL BufferedInputStream::closeInput( void ) + throw( NotConnectedException, + IOException, + RuntimeException ) +{ +} + + +void SAL_CALL BufferedInputStream::seek( sal_Int64 location ) + throw( IllegalArgumentException, + IOException, + RuntimeException ) +{ + if( 0 <= location && location < m_nBufferSize ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_nBufferLocation = sal::static_int_cast<sal_Int32>( location ); + } + else + throw IllegalArgumentException(); +} + + + +sal_Int64 SAL_CALL BufferedInputStream::getPosition( void ) + throw( IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return m_nBufferLocation; +} + + + +sal_Int64 SAL_CALL BufferedInputStream::getLength( void ) throw( IOException,RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return m_nBufferSize; +} diff --git a/xmlhelp/source/cxxhelp/provider/bufferedinputstream.hxx b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.hxx new file mode 100644 index 000000000000..afe7d3ba50ac --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <cppuhelper/weak.hxx> +#include <osl/mutex.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> + + +namespace chelp { + + class BufferedInputStream + : public cppu::OWeakObject, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XSeekable + { + private: + + sal_Int32 m_nBufferLocation; + sal_Int32 m_nBufferSize; + sal_Int8 *m_pBuffer; + osl::Mutex m_aMutex; + + public: + + BufferedInputStream( + const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream); + + ~BufferedInputStream(); + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL acquire( void ) throw(); + + virtual void SAL_CALL release( void ) throw(); + + + virtual sal_Int32 SAL_CALL readBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL readSomeBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL available( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL closeInput( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL seek( sal_Int64 location ) + throw( com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL getPosition( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL getLength( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + }; + + + extern com::sun::star::uno::Reference<com::sun::star::io::XInputStream> + turnToSeekable( + const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream); + +} diff --git a/xmlhelp/source/cxxhelp/provider/content.cxx b/xmlhelp/source/cxxhelp/provider/content.cxx new file mode 100644 index 000000000000..bbc39590547e --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/content.cxx @@ -0,0 +1,578 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/lang/IllegalAccessException.hpp> +#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> +#include <com/sun/star/io/XActiveDataStreamer.hpp> +#include <com/sun/star/ucb/XPersistentPropertySet.hpp> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <ucbhelper/contentidentifier.hxx> +#include <ucbhelper/propertyvalueset.hxx> +#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX +#include <ucbhelper/cancelcommandexecution.hxx> +#endif +#include "content.hxx" +#include "provider.hxx" +#include "resultset.hxx" +#include "databases.hxx" +#include "resultsetfactory.hxx" +#include "resultsetbase.hxx" +#include "resultsetforroot.hxx" +#include "resultsetforquery.hxx" + +using namespace com::sun::star; +using namespace chelp; + +//========================================================================= +//========================================================================= +// +// Content Implementation. +// +//========================================================================= +//========================================================================= + +Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, + ::ucbhelper::ContentProviderImplHelper* pProvider, + const uno::Reference< ucb::XContentIdentifier >& + Identifier, + Databases* pDatabases ) + : ContentImplHelper( rxSMgr, pProvider, Identifier ), + m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ), + m_pDatabases( pDatabases ) // not owner +{ +} + +//========================================================================= +// virtual +Content::~Content() +{ +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +// virtual +void SAL_CALL Content::acquire() + throw( ) +{ + ContentImplHelper::acquire(); +} + +//========================================================================= +// virtual +void SAL_CALL Content::release() + throw( ) +{ + ContentImplHelper::release(); +} + +//========================================================================= +// virtual +uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) + throw ( uno::RuntimeException ) +{ + uno::Any aRet; + return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); +} + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_COMMON_IMPL( Content ); + +//========================================================================= +// virtual +uno::Sequence< uno::Type > SAL_CALL Content::getTypes() + throw( uno::RuntimeException ) +{ + static cppu::OTypeCollection* pCollection = NULL; + + if ( !pCollection ) + { + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ); + if ( !pCollection ) + { + static cppu::OTypeCollection aCollection( + CPPU_TYPE_REF( lang::XTypeProvider ), + CPPU_TYPE_REF( lang::XServiceInfo ), + CPPU_TYPE_REF( lang::XComponent ), + CPPU_TYPE_REF( ucb::XContent ), + CPPU_TYPE_REF( ucb::XCommandProcessor ), + CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), + CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), + CPPU_TYPE_REF( beans::XPropertyContainer ), + CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), + CPPU_TYPE_REF( container::XChild ) ); + pCollection = &aCollection; + } + } + + return (*pCollection).getTypes(); +} + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +// virtual +rtl::OUString SAL_CALL Content::getImplementationName() + throw( uno::RuntimeException ) +{ + return rtl::OUString::createFromAscii( "CHelpContent" ); +} + +//========================================================================= +// virtual +uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() + throw( uno::RuntimeException ) +{ + uno::Sequence< rtl::OUString > aSNS( 1 ); + aSNS.getArray()[ 0 ] + = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME ); + return aSNS; +} + +//========================================================================= +// +// XContent methods. +// +//========================================================================= + +// virtual +rtl::OUString SAL_CALL Content::getContentType() + throw( uno::RuntimeException ) +{ + return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE ); +} + +//========================================================================= +// +// XCommandProcessor methods. +// +//========================================================================= + +//virtual +void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) + throw( uno::RuntimeException ) +{ +} + + + +class ResultSetForRootFactory + : public ResultSetFactory +{ +private: + + uno::Reference< lang::XMultiServiceFactory > m_xSMgr; + uno::Reference< ucb::XContentProvider > m_xProvider; + sal_Int32 m_nOpenMode; + uno::Sequence< beans::Property > m_seq; + uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; + URLParameter m_aURLParameter; + Databases* m_pDatabases; + + +public: + + ResultSetForRootFactory( + const uno::Reference< lang::XMultiServiceFactory >& xSMgr, + const uno::Reference< ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort, + URLParameter aURLParameter, + Databases* pDatabases ) + : m_xSMgr( xSMgr ), + m_xProvider( xProvider ), + m_nOpenMode( nOpenMode ), + m_seq( seq ), + m_seqSort( seqSort ), + m_aURLParameter( aURLParameter ), + m_pDatabases( pDatabases ) + { + } + + ResultSetBase* createResultSet() + { + return new ResultSetForRoot( m_xSMgr, + m_xProvider, + m_nOpenMode, + m_seq, + m_seqSort, + m_aURLParameter, + m_pDatabases ); + } +}; + + + +class ResultSetForQueryFactory + : public ResultSetFactory +{ +private: + + uno::Reference< lang::XMultiServiceFactory > m_xSMgr; + uno::Reference< ucb::XContentProvider > m_xProvider; + sal_Int32 m_nOpenMode; + uno::Sequence< beans::Property > m_seq; + uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; + URLParameter m_aURLParameter; + Databases* m_pDatabases; + + +public: + + ResultSetForQueryFactory( + const uno::Reference< lang::XMultiServiceFactory >& xSMgr, + const uno::Reference< ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort, + URLParameter aURLParameter, + Databases* pDatabases ) + : m_xSMgr( xSMgr ), + m_xProvider( xProvider ), + m_nOpenMode( nOpenMode ), + m_seq( seq ), + m_seqSort( seqSort ), + m_aURLParameter( aURLParameter ), + m_pDatabases( pDatabases ) + { + } + + ResultSetBase* createResultSet() + { + return new ResultSetForQuery( m_xSMgr, + m_xProvider, + m_nOpenMode, + m_seq, + m_seqSort, + m_aURLParameter, + m_pDatabases ); + } +}; + + + +// virtual +uno::Any SAL_CALL Content::execute( + const ucb::Command& aCommand, + sal_Int32 CommandId, + const uno::Reference< ucb::XCommandEnvironment >& Environment ) + throw( uno::Exception, + ucb::CommandAbortedException, + uno::RuntimeException ) +{ + uno::Any aRet; + + if ( aCommand.Name.compareToAscii( "getPropertyValues" ) == 0 ) + { + uno::Sequence< beans::Property > Properties; + if ( !( aCommand.Argument >>= Properties ) ) + { + aRet <<= lang::IllegalArgumentException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + aRet <<= getPropertyValues( Properties ); + } + else if ( aCommand.Name.compareToAscii( "setPropertyValues" ) == 0 ) + { + uno::Sequence<beans::PropertyValue> propertyValues; + + if( ! ( aCommand.Argument >>= propertyValues ) ) { + aRet <<= lang::IllegalArgumentException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + uno::Sequence< uno::Any > ret(propertyValues.getLength()); + uno::Sequence< beans::Property > props(getProperties(Environment)); + // No properties can be set + for(sal_Int32 i = 0; i < ret.getLength(); ++i) { + ret[i] <<= beans::UnknownPropertyException(); + for(sal_Int32 j = 0; j < props.getLength(); ++j) + if(props[j].Name == propertyValues[i].Name) { + ret[i] <<= lang::IllegalAccessException(); + break; + } + } + + aRet <<= ret; + } + else if ( aCommand.Name.compareToAscii( "getPropertySetInfo" ) == 0 ) + { + // Note: Implemented by base class. + aRet <<= getPropertySetInfo( Environment ); + } + else if ( aCommand.Name.compareToAscii( "getCommandInfo" ) == 0 ) + { + // Note: Implemented by base class. + aRet <<= getCommandInfo( Environment ); + } + else if ( aCommand.Name.compareToAscii( "open" ) == 0 ) + { + ucb::OpenCommandArgument2 aOpenCommand; + if ( !( aCommand.Argument >>= aOpenCommand ) ) + { + aRet <<= lang::IllegalArgumentException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + uno::Reference< io::XActiveDataSink > xActiveDataSink( + aOpenCommand.Sink, uno::UNO_QUERY); + + if(xActiveDataSink.is()) + m_aURLParameter.open(m_xSMgr, + aCommand, + CommandId, + Environment, + xActiveDataSink); + + uno::Reference< io::XActiveDataStreamer > xActiveDataStreamer( + aOpenCommand.Sink, uno::UNO_QUERY); + + if(xActiveDataStreamer.is()) { + aRet <<= ucb::UnsupportedDataSinkException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + uno::Reference< io::XOutputStream > xOutputStream( + aOpenCommand.Sink, uno::UNO_QUERY); + + if(xOutputStream.is() ) + m_aURLParameter.open(m_xSMgr, + aCommand, + CommandId, + Environment, + xOutputStream); + + if( m_aURLParameter.isRoot() ) + { + uno::Reference< ucb::XDynamicResultSet > xSet + = new DynamicResultSet( + m_xSMgr, + this, + aOpenCommand, + Environment, + new ResultSetForRootFactory( + m_xSMgr, + m_xProvider.get(), + aOpenCommand.Mode, + aOpenCommand.Properties, + aOpenCommand.SortingInfo, + m_aURLParameter, + m_pDatabases)); + aRet <<= xSet; + } + else if( m_aURLParameter.isQuery() ) + { + uno::Reference< ucb::XDynamicResultSet > xSet + = new DynamicResultSet( + m_xSMgr, + this, + aOpenCommand, + Environment, + new ResultSetForQueryFactory( + m_xSMgr, + m_xProvider.get(), + aOpenCommand.Mode, + aOpenCommand.Properties, + aOpenCommand.SortingInfo, + m_aURLParameter, + m_pDatabases ) ); + aRet <<= xSet; + } + } + else + { + ////////////////////////////////////////////////////////////////// + // Unsupported command + ////////////////////////////////////////////////////////////////// + aRet <<= ucb::UnsupportedCommandException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + return aRet; +} + + + + +//========================================================================= +uno::Reference< sdbc::XRow > Content::getPropertyValues( + const uno::Sequence< beans::Property >& rProperties ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = + new ::ucbhelper::PropertyValueSet( m_xSMgr ); + + for ( sal_Int32 n = 0; n < rProperties.getLength(); ++n ) + { + const beans::Property& rProp = rProperties[n]; + + if ( rProp.Name.compareToAscii( "ContentType" ) == 0 ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( + "application/vnd.sun.star.help" ) ); + else if( rProp.Name.compareToAscii( "Title" ) == 0 ) + xRow->appendString ( rProp,m_aURLParameter.get_title() ); + else if( rProp.Name.compareToAscii( "IsReadOnly" ) == 0 ) + xRow->appendBoolean( rProp,true ); + else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 ) + xRow->appendBoolean( + rProp, + m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); + else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 ) + xRow->appendBoolean( + rProp, + ! m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); + else if( rProp.Name.compareToAscii( "IsErrorDocument" ) == 0 ) + xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() ); + else if( rProp.Name.compareToAscii( "MediaType" ) == 0 ) + if( m_aURLParameter.isPicture() ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( "image/gif" ) ); + else if( m_aURLParameter.isActive() ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( "text/plain" ) ); + else if( m_aURLParameter.isFile() ) + xRow->appendString( + rProp,rtl::OUString::createFromAscii( "text/html" ) ); + else if( m_aURLParameter.isRoot() ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( "text/css" ) ); + else + xRow->appendVoid( rProp ); + else if( m_aURLParameter.isModule() ) + if( rProp.Name.compareToAscii( "KeywordList" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getKeywordList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "KeywordRef" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getIdList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "KeywordAnchorForRef" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getAnchorList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "KeywordTitleForRef" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getTitleList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "SearchScopes" ) == 0 ) + { + uno::Sequence< rtl::OUString > seq( 2 ); + seq[0] = rtl::OUString::createFromAscii( "Heading" ); + seq[1] = rtl::OUString::createFromAscii( "FullText" ); + uno::Any aAny; + aAny <<= seq; + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "Order" ) == 0 ) + { + StaticModuleInformation *inf = + m_pDatabases->getStaticInformationForModule( + m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= sal_Int32( inf->get_order() ); + xRow->appendObject( rProp,aAny ); + } + else + xRow->appendVoid( rProp ); + else if( rProp.Name.compareToAscii( "AnchorName" ) == 0 && + m_aURLParameter.isFile() ) + xRow->appendString( rProp,m_aURLParameter.get_tag() ); + else + xRow->appendVoid( rProp ); + } + + return uno::Reference< sdbc::XRow >( xRow.get() ); +} diff --git a/xmlhelp/source/cxxhelp/provider/content.hxx b/xmlhelp/source/cxxhelp/provider/content.hxx new file mode 100644 index 000000000000..21bd24afb254 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/content.hxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CONTENT_HXX +#define _CONTENT_HXX + +#include <vos/ref.hxx> +#include <ucbhelper/contenthelper.hxx> +#include <com/sun/star/io/XInputStream.hpp> + +#include "urlparameter.hxx" + +namespace com { namespace sun { namespace star { namespace beans { + struct Property; + struct PropertyValue; +} } } } + +namespace com { namespace sun { namespace star { namespace sdbc { + class XRow; +} } } } + +namespace chelp +{ + +//========================================================================= + +// UNO service name for the content. +#define MYUCP_CONTENT_SERVICE_NAME \ + "com.sun.star.ucb.CHelpContent" + +//========================================================================= + + class Databases; + + struct ContentProperties + { + ::rtl::OUString aTitle; // Title + ::rtl::OUString aContentType; // ContentType + sal_Bool bIsDocument; // IsDocument + sal_Bool bIsFolder; // IsFolder + + ContentProperties() + : bIsDocument( sal_True ), bIsFolder( sal_False ) {} + }; + +//========================================================================= + + class Content : public ::ucbhelper::ContentImplHelper + { + public: + + Content( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::ucbhelper::ContentProviderImplHelper* pProvider, + const ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentIdentifier >& Identifier, + Databases* pDatabases ); + + virtual ~Content(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL + getImplementationName() + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw( ::com::sun::star::uno::RuntimeException ); + + // XContent + virtual rtl::OUString SAL_CALL + getContentType() + throw( com::sun::star::uno::RuntimeException ); + + // XCommandProcessor + virtual com::sun::star::uno::Any SAL_CALL + execute( const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& Environment ) + throw( com::sun::star::uno::Exception, + com::sun::star::ucb::CommandAbortedException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + abort( sal_Int32 CommandId ) + throw( com::sun::star::uno::RuntimeException ); + + + private: + + // private members; + + ContentProperties m_aProps; + URLParameter m_aURLParameter; + Databases* m_pDatabases; + + + // private methods + + virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property > + getProperties( const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment > & xEnv ); + virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo > + getCommands( const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment > & xEnv ); + + virtual ::rtl::OUString getParentURL() { return ::rtl::OUString(); } + + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > + getPropertyValues( const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::Property >& rProperties ); + void setPropertyValues( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& rValues ); + + + }; + +} + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/contentcaps.cxx b/xmlhelp/source/cxxhelp/provider/contentcaps.cxx new file mode 100644 index 000000000000..cae428bb70c9 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/contentcaps.cxx @@ -0,0 +1,247 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/ucb/CommandInfo.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/uno/Sequence.hxx> + +#include "content.hxx" + +using namespace com::sun; +using namespace com::sun::star; + +using namespace chelp; + +// virtual +uno::Sequence< beans::Property > Content::getProperties( + const uno::Reference< star::ucb::XCommandEnvironment > & /*xEnv*/ ) +{ + bool withMediaType = m_aURLParameter.isFile() || m_aURLParameter.isRoot(); + bool isModule = m_aURLParameter.isModule(); + bool isFile = m_aURLParameter.isFile(); + + sal_Int32 num = withMediaType ? 7 : 6; + if( isModule ) num+=6; + if( isFile ) num++; + + uno::Sequence< beans::Property > props(num); + + sal_Int32 idx = 0; + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsErrorDocument" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + if( withMediaType ) + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + if( isModule ) + { + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Order" ) ), + -1, + getCppuType( static_cast< sal_Int32* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeywordList" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< rtl::OUString >* >( + 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeywordRef" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< uno::Sequence< rtl::OUString > >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "KeywordTitleForRef" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< uno::Sequence< rtl::OUString > >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "KeywordAnchorForRef" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< uno::Sequence< rtl::OUString > >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SearchScopes" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< rtl::OUString >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + } + + if( isFile ) + { + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AnchorName" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + } + + return props; +} + + + +//========================================================================= +// virtual +uno::Sequence< star::ucb::CommandInfo > Content::getCommands( + const uno::Reference< star::ucb::XCommandEnvironment > & /*xEnv*/ ) +{ +// osl::MutexGuard aGuard( m_aMutex ); + + //================================================================= + // + // Supported commands + // + //================================================================= + +#define COMMAND_COUNT 5 + + static const star::ucb::CommandInfo aCommandInfoTable[] = + { + /////////////////////////////////////////////////////////////// + // Required commands + /////////////////////////////////////////////////////////////// + star::ucb::CommandInfo( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ), + -1, + getCppuVoidType() + ), + star::ucb::CommandInfo( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ), + -1, + getCppuVoidType() + ), + star::ucb::CommandInfo( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ), + -1, + getCppuType( + static_cast< uno::Sequence< beans::Property > * >( 0 ) ) + ), + star::ucb::CommandInfo( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ), + -1, + getCppuType( + static_cast< uno::Sequence< beans::PropertyValue > * >( 0 ) ) + ), + star::ucb::CommandInfo( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ), + -1, + getCppuType( + static_cast< star::ucb::OpenCommandArgument2 * >( 0 ) ) + ) + }; + + return uno::Sequence< star::ucb::CommandInfo >( + aCommandInfoTable, COMMAND_COUNT ); +} + diff --git a/xmlhelp/source/cxxhelp/provider/databases.cxx b/xmlhelp/source/cxxhelp/provider/databases.cxx new file mode 100644 index 000000000000..d798f6c42f81 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/databases.cxx @@ -0,0 +1,2265 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include "db.hxx" +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <osl/thread.h> +#include <rtl/uri.hxx> +#include <osl/file.hxx> +#include <rtl/memory.h> +#include <com/sun/star/lang/Locale.hpp> +#include <rtl/ustrbuf.hxx> +#include "inputstream.hxx" +#include <algorithm> +#include <string.h> + +// Extensible help +#include "com/sun/star/deployment/ExtensionManager.hpp" +#include "com/sun/star/deployment/thePackageManagerFactory.hpp" +#include <comphelper/processfactory.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/beans/Optional.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <comphelper/locale.hxx> + +#include <com/sun/star/awt/XToolkit.hpp> +#include <com/sun/star/awt/XExtendedToolkit.hpp> +#include <com/sun/star/awt/XWindowPeer.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> + +#include <l10ntools/compilehelp.hxx> +#include <comphelper/storagehelper.hxx> + +#include "databases.hxx" +#include "urlparameter.hxx" + +using namespace chelp; +using namespace berkeleydbproxy; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; +using namespace com::sun::star::container; +using namespace com::sun::star::i18n; +using namespace com::sun::star::lang; +using namespace com::sun::star::deployment; +using namespace com::sun::star::beans; + + +static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); +static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) ); +static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) ); + +rtl::OUString Databases::expandURL( const rtl::OUString& aURL ) +{ + osl::MutexGuard aGuard( m_aMutex ); + rtl::OUString aRetURL = expandURL( aURL, m_xContext ); + return aRetURL; +} + +rtl::OUString Databases::expandURL( const rtl::OUString& aURL, Reference< uno::XComponentContext > xContext ) +{ + static Reference< util::XMacroExpander > xMacroExpander; + static Reference< uri::XUriReferenceFactory > xFac; + + if( !xContext.is() ) + return rtl::OUString(); + + if( !xMacroExpander.is() || !xFac.is() ) + { + Reference< XMultiComponentFactory > xSMgr( xContext->getServiceManager(), UNO_QUERY ); + + xFac = Reference< uri::XUriReferenceFactory >( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY ); + if( !xFac.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ), + Reference< XInterface >() ); + } + + xMacroExpander = Reference< util::XMacroExpander >( + xContext->getValueByName( + ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), + UNO_QUERY_THROW ); + } + + rtl::OUString aRetURL = aURL; + if( xMacroExpander.is() ) + { + Reference< uri::XUriReference > uriRef; + for (;;) + { + uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY ); + if ( uriRef.is() ) + { + Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); + if( !sxUri.is() ) + break; + + aRetURL = sxUri->expand( xMacroExpander ); + } + } + } + return aRetURL; +} + +Databases::Databases( sal_Bool showBasic, + const rtl::OUString& instPath, + const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths, + const rtl::OUString& productName, + const rtl::OUString& productVersion, + const rtl::OUString& styleSheet, + Reference< uno::XComponentContext > xContext ) + : m_xContext( xContext ), + m_bShowBasic(showBasic), + m_nErrorDocLength( 0 ), + m_pErrorDoc( 0 ), + m_nCustomCSSDocLength( 0 ), + m_pCustomCSSDoc( 0 ), + m_aCSS(styleSheet.toAsciiLowerCase()), + newProdName(rtl::OUString::createFromAscii( "$[officename]" ) ), + newProdVersion(rtl::OUString::createFromAscii( "$[officeversion]" ) ), + prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ), + prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ), + vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ), + vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ), + vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) ), + m_aImagesZipPaths( imagesZipPaths ), + m_nSymbolsStyle( 0 ) +{ + m_xSMgr = Reference< XMultiComponentFactory >( m_xContext->getServiceManager(), UNO_QUERY ); + + m_vAdd[0] = 12; + m_vAdd[1] = 15; + m_vAdd[2] = 11; + m_vAdd[3] = 14; + m_vAdd[4] = 12; + m_vAdd[5] = 13; + m_vAdd[6] = 16; + + m_vReplacement[0] = productName; + m_vReplacement[1] = productVersion; + // m_vReplacement[2...4] (vendorName/-Version/-Short) are empty strings + m_vReplacement[5] = productName; + m_vReplacement[6] = productVersion; + + setInstallPath( instPath ); + + m_xSFA = Reference< ucb::XSimpleFileAccess >( + m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), + m_xContext ), UNO_QUERY_THROW ); +} + +Databases::~Databases() +{ + // release stylesheet + + delete[] m_pCustomCSSDoc; + + // release errorDocument + + delete[] m_pErrorDoc; + + // unload the databases + + { + // DatabasesTable + DatabasesTable::iterator it = m_aDatabases.begin(); + while( it != m_aDatabases.end() ) + { + if( it->second ) + it->second->close( 0 ); + delete it->second; + ++it; + } + } + + { + // ModInfoTable + + ModInfoTable::iterator it = m_aModInfo.begin(); + while( it != m_aModInfo.end() ) + { + delete it->second; + ++it; + } + } + + { + // KeywordInfoTable + + KeywordInfoTable::iterator it = m_aKeywordInfo.begin(); + while( it != m_aKeywordInfo.end() ) + { + delete it->second; + ++it; + } + } +} + +static bool impl_getZipFile( + Sequence< rtl::OUString > & rImagesZipPaths, + const rtl::OUString & rZipName, + rtl::OUString & rFileName ) +{ + const rtl::OUString *pPathArray = rImagesZipPaths.getArray(); + for ( int i = 0; i < rImagesZipPaths.getLength(); ++i ) + { + rFileName = pPathArray[ i ]; + if ( rFileName.getLength() ) + { + if ( 1 + rFileName.lastIndexOf( '/' ) != rFileName.getLength() ) + { + rFileName += rtl::OUString::createFromAscii( "/" ); + } + rFileName += rZipName; + + // test existence + osl::DirectoryItem aDirItem; + if ( osl::DirectoryItem::get( rFileName, aDirItem ) == osl::FileBase::E_None ) + return true; + } + } + return false; +} + +rtl::OString Databases::getImagesZipFileURL() +{ + //sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle(); + sal_Int16 nSymbolsStyle = 0; + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProvider( + m_xSMgr ->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"), m_xContext), uno::UNO_QUERY_THROW); + + // set root path + uno::Sequence < uno::Any > lParams(1); + beans::PropertyValue aParam ; + aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); + aParam.Value <<= ::rtl::OUString::createFromAscii("org.openoffice.Office.Common"); + lParams[0] = uno::makeAny(aParam); + + // open it + uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), + lParams) ); + + bool bChanged = false; + uno::Reference< container::XHierarchicalNameAccess > xAccess(xCFG, uno::UNO_QUERY_THROW); + uno::Any aResult = xAccess->getByHierarchicalName(::rtl::OUString::createFromAscii("Misc/SymbolSet")); + if ( (aResult >>= nSymbolsStyle) && m_nSymbolsStyle != nSymbolsStyle ) + { + m_nSymbolsStyle = nSymbolsStyle; + bChanged = true; + } + + if ( !m_aImagesZipFileURL.getLength() || bChanged ) + { + rtl::OUString aImageZip, aSymbolsStyleName; + aResult = xAccess->getByHierarchicalName(::rtl::OUString::createFromAscii("Misc/SymbolStyle")); + aResult >>= aSymbolsStyleName; + + bool bFound = false; + if ( aSymbolsStyleName.getLength() != 0 ) + { + rtl::OUString aZipName = rtl::OUString::createFromAscii( "images_" ); + aZipName += aSymbolsStyleName; + aZipName += rtl::OUString::createFromAscii( ".zip" ); + + bFound = impl_getZipFile( m_aImagesZipPaths, aZipName, aImageZip ); + } + + if ( ! bFound ) + bFound = impl_getZipFile( m_aImagesZipPaths, rtl::OUString::createFromAscii( "images.zip" ), aImageZip ); + + if ( ! bFound ) + aImageZip = rtl::OUString(); + + m_aImagesZipFileURL = rtl::OUStringToOString( + rtl::Uri::encode( + aImageZip, + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ), RTL_TEXTENCODING_UTF8 ); + } + } + catch ( NoSuchElementException const & ) + { + } + + return m_aImagesZipFileURL; +} + +void Databases::replaceName( rtl::OUString& oustring ) const +{ + sal_Int32 idx = -1,idx1 = -1,idx2 = -1,k = 0,off; + bool cap = false; + rtl::OUStringBuffer aStrBuf( 0 ); + + while( true ) + { + ++idx; + idx1 = oustring.indexOf( sal_Unicode('%'),idx); + idx2 = oustring.indexOf( sal_Unicode('$'),idx); + + if(idx1 == -1 && idx2 == -1) + break; + + if(idx1 == -1) + idx = idx2; + else if(idx2 == -1) + idx = idx1; + else { + // no index is zero + if(idx1 < idx2) + idx = idx1; + else if(idx2 < idx1 ) + idx = idx2; + } + + if( oustring.indexOf( prodName,idx ) == idx ) + off = PRODUCTNAME; + else if( oustring.indexOf( prodVersion,idx ) == idx ) + off = PRODUCTVERSION; + else if( oustring.indexOf( vendName,idx ) == idx ) + off = VENDORNAME; + else if( oustring.indexOf( vendVersion,idx ) == idx ) + off = VENDORVERSION; + else if( oustring.indexOf( vendShort,idx ) == idx ) + off = VENDORSHORT; + else if( oustring.indexOf( newProdName,idx ) == idx ) + off = NEWPRODUCTNAME; + else if( oustring.indexOf( newProdVersion,idx ) == idx ) + off = NEWPRODUCTVERSION; + else + off = -1; + + if( off != -1 ) + { + if( ! cap ) + { + cap = true; + aStrBuf.ensureCapacity( 256 ); + } + + aStrBuf.append( &oustring.getStr()[k],idx - k ); + aStrBuf.append( m_vReplacement[off] ); + k = idx + m_vAdd[off]; + } + } + + if( cap ) + { + if( k < oustring.getLength() ) + aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k ); + oustring = aStrBuf.makeStringAndClear(); + } +} + + + + +rtl::OUString Databases::getInstallPathAsSystemPath() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if( ! m_aInstallDirectoryAsSystemPath.getLength() ) + { +#ifdef DBG_UTIL + bool bla = + osl::FileBase::E_None == + osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath ); + VOS_ENSURE( bla,"HelpProvider, no installpath" ); +#else + osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath ); +#endif + } + + return m_aInstallDirectoryAsSystemPath; +} + + + + +rtl::OUString Databases::getInstallPathAsURL() +{ + osl::MutexGuard aGuard( m_aMutex ); + + return m_aInstallDirectory; +} + + +const std::vector< rtl::OUString >& Databases::getModuleList( const rtl::OUString& Language ) +{ + if( m_avModules.size() == 0 ) + { + rtl::OUString fileName,dirName = getInstallPathAsURL() + processLang( Language ); + osl::Directory dirFile( dirName ); + + osl::DirectoryItem aDirItem; + osl::FileStatus aStatus( FileStatusMask_FileName ); + + sal_Int32 idx; + + if( osl::FileBase::E_None != dirFile.open() ) + return m_avModules; + + while( dirFile.getNextItem( aDirItem ) == osl::FileBase::E_None && + aDirItem.getFileStatus( aStatus ) == osl::FileBase::E_None ) + { + if( ! aStatus.isValid( FileStatusMask_FileName ) ) + continue; + + fileName = aStatus.getFileName(); + + // Check, whether fileName is of the form *.cfg + idx = fileName.lastIndexOf( sal_Unicode( '.' ) ); + + if( idx == -1 ) + continue; + + const sal_Unicode* str = fileName.getStr(); + + if( fileName.getLength() == idx + 4 && + ( str[idx + 1] == 'c' || str[idx + 1] == 'C' ) && + ( str[idx + 2] == 'f' || str[idx + 2] == 'F' ) && + ( str[idx + 3] == 'g' || str[idx + 3] == 'G' ) && + ( fileName = fileName.copy(0,idx).toAsciiLowerCase() ).compareToAscii( "picture" ) != 0 ) { + if(! m_bShowBasic && fileName.compareToAscii("sbasic") == 0 ) + continue; + m_avModules.push_back( fileName ); + } + } + } + return m_avModules; +} + + + +StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OUString& Module, + const rtl::OUString& Language ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Module; + + std::pair< ModInfoTable::iterator,bool > aPair = + m_aModInfo.insert( ModInfoTable::value_type( key,0 ) ); + + ModInfoTable::iterator it = aPair.first; + + if( aPair.second && ! it->second ) + { + osl::File cfgFile( getInstallPathAsURL() + + key + + rtl::OUString::createFromAscii( ".cfg" ) ); + + if( osl::FileBase::E_None != cfgFile.open( OpenFlag_Read ) ) + it->second = 0; + else + { + sal_uInt32 pos = 0; + sal_uInt64 nRead; + sal_Char buffer[2048]; + sal_Unicode lineBuffer[1028]; + rtl::OUString fileContent; + + while( osl::FileBase::E_None == cfgFile.read( &buffer,2048,nRead ) && nRead ) + fileContent += rtl::OUString( buffer,sal_Int32( nRead ),RTL_TEXTENCODING_UTF8 ); + + cfgFile.close(); + + const sal_Unicode* str = fileContent.getStr(); + rtl::OUString current,lang_,program,startid,title,heading,fulltext; + rtl::OUString order = rtl::OUString::createFromAscii( "1" ); + + for( sal_Int32 i = 0;i < fileContent.getLength();i++ ) + { + sal_Unicode ch = str[ i ]; + if( ch == sal_Unicode( '\n' ) || ch == sal_Unicode( '\r' ) ) + { + if( pos ) + { + current = rtl::OUString( lineBuffer,pos ); + + if( current.compareToAscii( "Title",5 ) == 0 ) + { + title = current.copy( current.indexOf(sal_Unicode( '=' ) ) + 1 ); + } + else if( current.compareToAscii( "Start",5 ) == 0 ) + { + startid = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Language",8 ) == 0 ) + { + lang_ = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Program",7 ) == 0 ) + { + program = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Heading",7 ) == 0 ) + { + heading = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "FullText",8 ) == 0 ) + { + fulltext = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Order",5 ) == 0 ) + { + order = current.copy( current.indexOf('=') + 1 ); + } + } + pos = 0; + } + else + lineBuffer[ pos++ ] = ch; + } + replaceName( title ); + it->second = new StaticModuleInformation( title, + startid, + program, + heading, + fulltext, + order ); + } + } + + return it->second; +} + + + + +rtl::OUString Databases::processLang( const rtl::OUString& Language ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::OUString ret; + LangSetTable::iterator it = m_aLangSet.find( Language ); + + if( it == m_aLangSet.end() ) + { + sal_Int32 idx; + osl::DirectoryItem aDirItem; + + if( osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language,aDirItem ) ) + { + ret = Language; + m_aLangSet[ Language ] = ret; + } + else if( ( ( idx = Language.indexOf( '-' ) ) != -1 || + ( idx = Language.indexOf( '_' ) ) != -1 ) && + osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language.copy( 0,idx ), + aDirItem ) ) + { + ret = Language.copy( 0,idx ); + m_aLangSet[ Language ] = ret; + } + } + else + ret = it->second; + + return ret; +} + + +rtl::OUString Databases::country( const rtl::OUString& Language ) +{ + sal_Int32 idx; + if( ( idx = Language.indexOf( '-' ) ) != -1 || + ( idx = Language.indexOf( '_' ) ) != -1 ) + return Language.copy( 1+idx ); + + return rtl::OUString(); +} + + + +Db* Databases::getBerkeley( const rtl::OUString& Database, + const rtl::OUString& Language, bool helpText, + const rtl::OUString* pExtensionPath ) +{ + if( ! Database.getLength() || ! Language.getLength() ) + return 0; + + osl::MutexGuard aGuard( m_aMutex ); + + + rtl::OUString aFileExt( rtl::OUString::createFromAscii( helpText ? ".ht" : ".db" ) ); + rtl::OUString dbFileName = aSlash + Database + aFileExt; + rtl::OUString key; + if( pExtensionPath == NULL ) + key = processLang( Language ) + dbFileName; + else + key = *pExtensionPath + Language + dbFileName; // make unique, don't change language + + std::pair< DatabasesTable::iterator,bool > aPair = + m_aDatabases.insert( DatabasesTable::value_type( key,0 ) ); + + DatabasesTable::iterator it = aPair.first; + + if( aPair.second && ! it->second ) + { + Db* table = new Db(); + + rtl::OUString fileNameOU; + if( pExtensionPath ) + { + rtl::OUString aExpandedURL = expandURL( *pExtensionPath ); + aExpandedURL += Language + dbFileName; + osl::FileBase::getSystemPathFromFileURL( aExpandedURL, fileNameOU ); + } + else + fileNameOU = getInstallPathAsSystemPath() + key; + + + rtl::OString fileName( fileNameOU.getStr(),fileNameOU.getLength(),osl_getThreadTextEncoding() ); + + rtl::OUString fileNameDBHelp( fileNameOU ); + if( pExtensionPath != NULL ) + fileNameDBHelp += rtl::OUString::createFromAscii( "_" ); + if( m_xSFA->exists( fileNameDBHelp ) ) + { + DBHelp* pDBHelp = new DBHelp( fileNameDBHelp, m_xSFA ); + table->setDBHelp( pDBHelp ); + +#ifdef TEST_DBHELP + bool bSuccess; + bool bOldDbAccess = false; + bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess ); + + bOldDbAccess = true; + bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess ); +#endif + } + else if( table->open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + table->close( 0 ); + delete table; + table = 0; + } + + it->second = table; + } + + return it->second; +} + +Reference< XCollator > +Databases::getCollator( const rtl::OUString& Language, + const rtl::OUString& System ) +{ + (void)System; + + rtl::OUString key = Language; + + osl::MutexGuard aGuard( m_aMutex ); + + CollatorTable::iterator it = + m_aCollatorTable.insert( CollatorTable::value_type( key,0 ) ).first; + + if( ! it->second.is() ) + { + it->second = + Reference< XCollator > ( + m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ), + m_xContext ), UNO_QUERY ); + rtl::OUString langStr = processLang(Language); + rtl::OUString countryStr = country(Language); + if( !countryStr.getLength() ) + { + if( langStr.compareToAscii("de") == 0 ) + countryStr = rtl::OUString::createFromAscii("DE"); + else if( langStr.compareToAscii("en") == 0 ) + countryStr = rtl::OUString::createFromAscii("US"); + else if( langStr.compareToAscii("es") == 0 ) + countryStr = rtl::OUString::createFromAscii("ES"); + else if( langStr.compareToAscii("it") == 0 ) + countryStr = rtl::OUString::createFromAscii("IT"); + else if( langStr.compareToAscii("fr") == 0 ) + countryStr = rtl::OUString::createFromAscii("FR"); + else if( langStr.compareToAscii("sv") == 0 ) + countryStr = rtl::OUString::createFromAscii("SE"); + else if( langStr.compareToAscii("ja") == 0 ) + countryStr = rtl::OUString::createFromAscii("JP"); + else if( langStr.compareToAscii("ko") == 0 ) + countryStr = rtl::OUString::createFromAscii("KR"); + } + it->second->loadDefaultCollator( Locale( langStr, + countryStr, + rtl::OUString() ), + 0 ); + } + + return it->second; +} + + + +namespace chelp { + + struct KeywordElementComparator + { + KeywordElementComparator( const Reference< XCollator >& xCollator ) + : m_xCollator( xCollator ) + { } + + bool operator()( const KeywordInfo::KeywordElement& la, + const KeywordInfo::KeywordElement& ra ) const + { + const rtl::OUString& l = la.key; + const rtl::OUString& r = ra.key; + + bool ret; + + if( m_xCollator.is() ) + { + sal_Int32 l1 = l.indexOf( sal_Unicode( ';' ) ); + sal_Int32 l3 = ( l1 == -1 ? l.getLength() : l1 ); + + sal_Int32 r1 = r.indexOf( sal_Unicode( ';' ) ); + sal_Int32 r3 = ( r1 == -1 ? r.getLength() : r1 ); + + sal_Int32 c1 = m_xCollator->compareSubstring( l,0,l3,r,0,r3 ); + + if( c1 == +1 ) + ret = false; + else if( c1 == 0 ) + { + sal_Int32 l2 = l.getLength() - l1 - 1; + sal_Int32 r2 = r.getLength() - r1 - 1; + ret = ( m_xCollator->compareSubstring( l,1+l1,l2,r,1+r1,r2 ) < 0 ); + } + else + ret = true; + } + else + ret = bool( l < r ); + + return ret; + } + + Reference< XCollator > m_xCollator; + }; // end struct KeywordElementComparator + +} + + + +KeywordInfo::KeywordElement::KeywordElement( Databases *pDatabases, + Db* pDb, + rtl::OUString& ky, + rtl::OUString& data ) + : key( ky ) +{ + pDatabases->replaceName( key ); + init( pDatabases,pDb,data ); +} + + + +void KeywordInfo::KeywordElement::init( Databases *pDatabases,Db* pDb,const rtl::OUString& ids ) +{ + const sal_Unicode* idstr = ids.getStr(); + std::vector< rtl::OUString > id,anchor; + int idx = -1,k; + while( ( idx = ids.indexOf( ';',k = ++idx ) ) != -1 ) + { + int h = ids.indexOf( sal_Unicode( '#' ),k ); + if( h < idx ) + { + // found an anchor + id.push_back( rtl::OUString( &idstr[k],h-k ) ); + anchor.push_back( rtl::OUString( &idstr[h+1],idx-h-1 ) ); + } + else + { + id.push_back( rtl::OUString( &idstr[k],idx-k ) ); + anchor.push_back( rtl::OUString() ); + } + } + + listId.realloc( id.size() ); + listAnchor.realloc( id.size() ); + listTitle.realloc( id.size() ); + + int nSize = 0; + const sal_Char* pData = NULL; + const sal_Char pEmpty[] = ""; + + for( sal_uInt32 i = 0; i < id.size(); ++i ) + { + listId[i] = id[i]; + listAnchor[i] = anchor[i]; + + nSize = 0; + pData = pEmpty; + if( pDb ) + { + rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 ); + DBHelp* pDBHelp = pDb->getDBHelp(); + if( pDBHelp != NULL ) + { + DBData aDBData; + bool bSuccess = pDBHelp->getValueForKey( idi, aDBData ); + if( bSuccess ) + { + nSize = aDBData.getSize(); + pData = aDBData.getData(); + } + } + else + { + Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ), + idi.getLength() ); + Dbt data; + pDb->get( 0,&key_,&data,0 ); + nSize = data.get_size(); + pData = static_cast<sal_Char*>( data.get_data() ); + } + } + + DbtToStringConverter converter( pData, nSize ); + + rtl::OUString title = converter.getTitle(); + pDatabases->replaceName( title ); + listTitle[i] = title; + } +} + + + +KeywordInfo::KeywordInfo( const std::vector< KeywordElement >& aVec ) + : listKey( aVec.size() ), + listId( aVec.size() ), + listAnchor( aVec.size() ), + listTitle( aVec.size() ) +{ + for( unsigned int i = 0; i < aVec.size(); ++i ) + { + listKey[i] = aVec[i].key; + listId[i] = aVec[i].listId; + listAnchor[i] = aVec[i].listAnchor; + listTitle[i] = aVec[i].listTitle; + } +} + +bool Databases::checkModuleMatchForExtension + ( const rtl::OUString& Database, const rtl::OUString& doclist ) +{ + bool bBelongsToDatabase = true; + + // Analyse doclist string to find module assignments + bool bFoundAtLeastOneModule = false; + bool bModuleMatch = false; + sal_Int32 nLen = doclist.getLength(); + sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') ); + if( nLastFound == -1 ) + nLastFound = nLen; + const sal_Unicode* pStr = doclist.getStr(); + sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') ); + while( nFound != -1 ) + { + // Simple optimization, stop if '_' is followed by "id" + if( nLen - nFound > 2 ) + { + if( pStr[ nFound + 1 ] == sal_Unicode('i') && + pStr[ nFound + 2 ] == sal_Unicode('d') ) + break; + } + + rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 ); + std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule ); + if( result != m_avModules.end() ) + { + bFoundAtLeastOneModule = true; + if( Database == aModule ) + { + bModuleMatch = true; + break; + } + } + + nLastFound = nFound; + if( nLastFound == 0 ) + break; + nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 ); + } + + if( bFoundAtLeastOneModule && !bModuleMatch ) + bBelongsToDatabase = false; + + return bBelongsToDatabase; +} + + +KeywordInfo* Databases::getKeyword( const rtl::OUString& Database, + const rtl::OUString& Language ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Database; + + std::pair< KeywordInfoTable::iterator,bool > aPair = + m_aKeywordInfo.insert( KeywordInfoTable::value_type( key,0 ) ); + + KeywordInfoTable::iterator it = aPair.first; + + if( aPair.second && ! it->second ) + { + std::vector<KeywordInfo::KeywordElement> aVector; + + KeyDataBaseFileIterator aDbFileIt( m_xContext, *this, Database, Language ); + rtl::OUString fileNameOU; + bool bExtension = false; + while( (fileNameOU = aDbFileIt.nextDbFile( bExtension )).getLength() > 0 ) + { + rtl::OString fileName( fileNameOU.getStr(), + fileNameOU.getLength(), + osl_getThreadTextEncoding() ); + + Db table; + + rtl::OUString fileNameDBHelp( fileNameOU ); + if( bExtension ) + fileNameDBHelp += rtl::OUString::createFromAscii( "_" ); + if( m_xSFA->exists( fileNameDBHelp ) ) + { + DBHelp aDBHelp( fileNameDBHelp, m_xSFA ); + + DBData aKey; + DBData aValue; + if( aDBHelp.startIteration() ) + { + Db* idmap = getBerkeley( Database,Language ); + + DBHelp* pDBHelp = idmap->getDBHelp(); + if( pDBHelp != NULL ) + { + bool bOptimizeForPerformance = true; + pDBHelp->releaseHashMap(); + pDBHelp->createHashMap( bOptimizeForPerformance ); + } + + while( aDBHelp.getNextKeyAndValue( aKey, aValue ) ) + { + rtl::OUString keyword( aKey.getData(), aKey.getSize(), + RTL_TEXTENCODING_UTF8 ); + rtl::OUString doclist( aValue.getData(), aValue.getSize(), + RTL_TEXTENCODING_UTF8 ); + + bool bBelongsToDatabase = true; + if( bExtension ) + bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist ); + + if( !bBelongsToDatabase ) + continue; + + aVector.push_back( KeywordInfo::KeywordElement( this, + idmap, + keyword, + doclist ) ); + } + aDBHelp.stopIteration(); + + if( pDBHelp != NULL ) + pDBHelp->releaseHashMap(); + } + +#ifdef TEST_DBHELP + bool bSuccess; + bool bOldDbAccess = false; + bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess ); + + bOldDbAccess = true; + bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess ); + + int nDummy = 0; +#endif + } + + else if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + Db* idmap = getBerkeley( Database,Language ); + + bool first = true; + + Dbc* cursor = 0; + table.cursor( 0,&cursor,0 ); + Dbt key_,data; + key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory + data.set_flags( DB_DBT_MALLOC ); + while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) ) + { + rtl::OUString keyword( static_cast<sal_Char*>(key_.get_data()), + key_.get_size(), + RTL_TEXTENCODING_UTF8 ); + rtl::OUString doclist( static_cast<sal_Char*>(data.get_data()), + data.get_size(), + RTL_TEXTENCODING_UTF8 ); + + bool bBelongsToDatabase = true; + if( bExtension ) + bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist ); + + if( !bBelongsToDatabase ) + continue; + + aVector.push_back( KeywordInfo::KeywordElement( this, + idmap, + keyword, + doclist ) ); + if( first ) + { + key_.set_flags( DB_DBT_REALLOC ); + data.set_flags( DB_DBT_REALLOC ); + first = false; + } + } + + if( cursor ) cursor->close(); + } + table.close( 0 ); + } + + // sorting + Reference< XCollator > xCollator = getCollator( Language,rtl::OUString()); + KeywordElementComparator aComparator( xCollator ); + std::sort(aVector.begin(),aVector.end(),aComparator); + + KeywordInfo* pInfo = it->second = new KeywordInfo( aVector ); + (void)pInfo; + } + + return it->second; +} + +Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& jar, + const rtl::OUString& Language ) +{ + if( ! jar.getLength() || + ! Language.getLength() ) + { + return Reference< XHierarchicalNameAccess >( 0 ); + } + rtl::OUString key = processLang(Language) + aSlash + jar; + + osl::MutexGuard aGuard( m_aMutex ); + + ZipFileTable::iterator it = + m_aZipFileTable.insert( ZipFileTable::value_type( key,Reference< XHierarchicalNameAccess >(0) ) ).first; + + if( ! it->second.is() ) + { + rtl::OUString zipFile; + try + { + // Extension jar file? Search for ? + sal_Int32 nQuestionMark1 = jar.indexOf( sal_Unicode('?') ); + sal_Int32 nQuestionMark2 = jar.lastIndexOf( sal_Unicode('?') ); + if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 ) + { + ::rtl::OUString aExtensionPath = jar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 ); + ::rtl::OUString aPureJar = jar.copy( nQuestionMark2 + 1 ); + + rtl::OUStringBuffer aStrBuf; + aStrBuf.append( aExtensionPath ); + aStrBuf.append( aSlash ); + aStrBuf.append( aPureJar ); + + zipFile = expandURL( aStrBuf.makeStringAndClear() ); + } + else + { + zipFile = getInstallPathAsURL() + key; + } + + Sequence< Any > aArguments( 2 ); + + XInputStream_impl* p = new XInputStream_impl( zipFile ); + if( p->CtorSuccess() ) + { + Reference< XInputStream > xInputStream( p ); + aArguments[ 0 ] <<= xInputStream; + } + else + { + delete p; + aArguments[ 0 ] <<= zipFile; + } + + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + + Reference< XInterface > xIfc + = m_xSMgr->createInstanceWithArgumentsAndContext( + rtl::OUString::createFromAscii( + "com.sun.star.packages.comp.ZipPackage" ), + aArguments, m_xContext ); + + if ( xIfc.is() ) + { + it->second = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY ); + + VOS_ENSURE( it->second.is(), + "ContentProvider::createPackage - " + "Got no hierarchical name access!" ); + + } + } + catch ( RuntimeException & ) + { + } + catch ( Exception & ) + { + } + } + + return it->second; +} + +Reference< XHierarchicalNameAccess > Databases::findJarFileForPath + ( const rtl::OUString& jar, const rtl::OUString& Language, + const rtl::OUString& path, rtl::OUString* o_pExtensionPath, + rtl::OUString* o_pExtensionRegistryPath ) +{ + Reference< XHierarchicalNameAccess > xNA; + if( ! jar.getLength() || + ! Language.getLength() ) + { + return xNA; + } + + JarFileIterator aJarFileIt( m_xContext, *this, jar, Language ); + Reference< XHierarchicalNameAccess > xTestNA; + Reference< deployment::XPackage > xParentPackageBundle; + while( (xTestNA = aJarFileIt.nextJarFile( xParentPackageBundle, o_pExtensionPath, o_pExtensionRegistryPath )).is() ) + { + if( xTestNA.is() && xTestNA->hasByHierarchicalName( path ) ) + { + bool bSuccess = true; + if( xParentPackageBundle.is() ) + { + rtl::OUString aIdentifierInPath; + sal_Int32 nFindSlash = path.indexOf( '/' ); + if( nFindSlash != -1 ) + aIdentifierInPath = path.copy( 0, nFindSlash ); + + beans::Optional<rtl::OUString> aIdentifierOptional = xParentPackageBundle->getIdentifier(); + if( aIdentifierInPath.getLength() && aIdentifierOptional.IsPresent ) + { + rtl::OUString aUnencodedIdentifier = aIdentifierOptional.Value; + rtl::OUString aIdentifier = rtl::Uri::encode( aUnencodedIdentifier, + rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 ); + + if( !aIdentifierInPath.equals( aIdentifier ) ) + { + // path does not start with extension identifier -> ignore + bSuccess = false; + } + } + else + { + // No identifier -> ignore + bSuccess = false; + } + } + + if( bSuccess ) + { + xNA = xTestNA; + break; + } + } + } + + return xNA; +} + +void Databases::popupDocument( URLParameter* urlPar,char **buffer,int *byteCount ) +{ + const char* pop1 = + " <html> " + " <head> " + " <help:css-file-link xmlns:help=\"http://openoffice.org/2000/help\"/> " + " </head> " + " <body> " + " <help:popup-cut Id=\""; + const sal_Int32 l1 = strlen( pop1 ); + + const char* pop3 = "\" Eid=\""; + const sal_Int32 l3 = strlen( pop3 ); + + const char* pop5 = + "\" xmlns:help=\"http://openoffice.org/2000/help\"></help:popup-cut> " + " </body> " + " </html>"; + const sal_Int32 l5 = strlen( pop5 ); + sal_Int32 l2,l4; + + rtl::OUString val = urlPar->get_id(); + rtl::OString pop2O( val.getStr(),l2 = val.getLength(),RTL_TEXTENCODING_UTF8 ); + const char* pop2 = pop2O.getStr(); + + val = urlPar->get_eid(); + rtl::OString pop4O( val.getStr(),l4 = val.getLength(),RTL_TEXTENCODING_UTF8 ); + const char* pop4 = pop4O.getStr(); + + (*byteCount) = l1 + l2 + l3 + l4 + l5; + + *buffer = new char[ 1+*byteCount ]; + + rtl_copyMemory( *buffer,pop1,l1 ); + rtl_copyMemory( *buffer+l1,pop2,l2 ); + rtl_copyMemory( *buffer+(l1+l2),pop3,l3 ); + rtl_copyMemory( *buffer+(l1+l2+l3),pop4,l4 ); + rtl_copyMemory( *buffer+(l1+l2+l3+l4),pop5,l5 ); + (*buffer)[*byteCount] = 0; +} + + +void Databases::changeCSS(const rtl::OUString& newStyleSheet) +{ + m_aCSS = newStyleSheet.toAsciiLowerCase(); + delete[] m_pCustomCSSDoc, m_pCustomCSSDoc = 0,m_nCustomCSSDocLength = 0; +} + + + +void Databases::cascadingStylesheet( const rtl::OUString& Language, + char** buffer, + int* byteCount ) +{ + if( ! m_pCustomCSSDoc ) + { + int retry = 2; + bool error = true; + rtl::OUString fileURL; + + sal_Bool bHighContrastMode = sal_False; + rtl::OUString aCSS( m_aCSS ); + if ( aCSS.compareToAscii( "default" ) == 0 ) + { + // #i50760: "default" needs to adapt HC mode + uno::Reference< awt::XToolkit > xToolkit = uno::Reference< awt::XToolkit >( + ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ) ), uno::UNO_QUERY ); + if ( xToolkit.is() ) + { + uno::Reference< awt::XExtendedToolkit > xExtToolkit( xToolkit, uno::UNO_QUERY ); + if ( xExtToolkit.is() ) + { + uno::Reference< awt::XTopWindow > xTopWindow = xExtToolkit->getActiveTopWindow(); + if ( xTopWindow.is() ) + { + uno::Reference< awt::XVclWindowPeer > xVclWindowPeer( xTopWindow, uno::UNO_QUERY ); + if ( xVclWindowPeer.is() ) + { + uno::Any aHCMode = xVclWindowPeer->getProperty( rtl::OUString::createFromAscii( "HighContrastMode" ) ); + if ( ( aHCMode >>= bHighContrastMode ) && bHighContrastMode ) + aCSS = rtl::OUString::createFromAscii( "highcontrastblack" ); + } + } + } + } + } + + while( error && retry ) + { + + if( retry == 2 ) + fileURL = + getInstallPathAsURL() + + processLang( Language ) + + rtl::OUString::createFromAscii( "/" ) + + aCSS + + rtl::OUString::createFromAscii( ".css" ); + else if( retry == 1 ) + fileURL = + getInstallPathAsURL() + + aCSS + + rtl::OUString::createFromAscii( ".css" ); + + osl::DirectoryItem aDirItem; + osl::File aFile( fileURL ); + osl::FileStatus aStatus( FileStatusMask_FileSize ); + + if( osl::FileBase::E_None == osl::DirectoryItem::get( fileURL,aDirItem ) && + osl::FileBase::E_None == aFile.open( OpenFlag_Read ) && + osl::FileBase::E_None == aDirItem.getFileStatus( aStatus ) ) + { + m_nCustomCSSDocLength = int( aStatus.getFileSize() ); + m_pCustomCSSDoc = new char[ 1 + m_nCustomCSSDocLength ]; + m_pCustomCSSDoc[ m_nCustomCSSDocLength ] = 0; + sal_uInt64 a = m_nCustomCSSDocLength,b = m_nCustomCSSDocLength; + aFile.read( m_pCustomCSSDoc,a,b ); + aFile.close(); + error = false; + } + + --retry; + if ( !retry && error && bHighContrastMode ) + { + // fall back to default css + aCSS = rtl::OUString::createFromAscii( "default" ); + retry = 2; + bHighContrastMode = sal_False; + } + } + + if( error ) + { + m_nCustomCSSDocLength = 0; + m_pCustomCSSDoc = new char[ 1 ]; // Initialize with 1 to avoid gcc compiler warning + } + } + + *byteCount = m_nCustomCSSDocLength; + *buffer = new char[ 1 + *byteCount ]; + (*buffer)[*byteCount] = 0; + rtl_copyMemory( *buffer,m_pCustomCSSDoc,m_nCustomCSSDocLength ); + +} + + +void Databases::setActiveText( const rtl::OUString& Module, + const rtl::OUString& Language, + const rtl::OUString& Id, + char** buffer, + int* byteCount ) +{ + DataBaseIterator aDbIt( m_xContext, *this, Module, Language, true ); + + // #i84550 Cache information about failed ids + rtl::OString id( Id.getStr(),Id.getLength(),RTL_TEXTENCODING_UTF8 ); + EmptyActiveTextSet::iterator it = m_aEmptyActiveTextSet.find( id ); + bool bFoundAsEmpty = ( it != m_aEmptyActiveTextSet.end() ); + Dbt data; + DBData aDBData; + + int nSize = 0; + const sal_Char* pData = NULL; + + bool bSuccess = false; + if( !bFoundAsEmpty ) + { + Db* db; + Dbt key( static_cast< void* >( const_cast< sal_Char* >( id.getStr() ) ),id.getLength() ); + while( !bSuccess && (db = aDbIt.nextDb()) != NULL ) + { + DBHelp* pDBHelp = db->getDBHelp(); + if( pDBHelp != NULL ) + { + bSuccess = pDBHelp->getValueForKey( id, aDBData ); + nSize = aDBData.getSize(); + pData = aDBData.getData(); + } + else + { + int err = db->get( 0, &key, &data, 0 ); + if( err == 0 ) + { + bSuccess = true; + nSize = data.get_size(); + pData = static_cast<sal_Char*>( data.get_data() ); + } + } + } + } + + if( bSuccess ) + { + // ensure existence of tmp after for + rtl::OString tmp; + for( int i = 0; i < nSize; ++i ) + if( pData[i] == '%' || pData[i] == '$' ) + { + // need of replacement + rtl::OUString temp = rtl::OUString( pData, nSize, RTL_TEXTENCODING_UTF8 ); + replaceName( temp ); + tmp = rtl::OString( temp.getStr(), + temp.getLength(), + RTL_TEXTENCODING_UTF8 ); + nSize = tmp.getLength(); + pData = tmp.getStr(); + break; + } + + *byteCount = nSize; + *buffer = new char[ 1 + nSize ]; + (*buffer)[nSize] = 0; + rtl_copyMemory( *buffer, pData, nSize ); + } + else + { + *byteCount = 0; + *buffer = new char[1]; // Initialize with 1 to avoid compiler warnings + if( !bFoundAsEmpty ) + m_aEmptyActiveTextSet.insert( id ); + } +} + + +void Databases::setInstallPath( const rtl::OUString& aInstDir ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + osl::FileBase::getFileURLFromSystemPath( aInstDir,m_aInstallDirectory ); + //TODO: check returned error code + + if( m_aInstallDirectory.lastIndexOf( sal_Unicode( '/' ) ) != m_aInstallDirectory.getLength() - 1 ) + m_aInstallDirectory += rtl::OUString::createFromAscii( "/" ); + + m_aInstallDirectoryWithoutEncoding = rtl::Uri::decode( m_aInstallDirectory, + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8 ); +} + + +//=================================================================== +// class ExtensionIteratorBase + +ExtensionHelpExistanceMap ExtensionIteratorBase::aHelpExistanceMap; + +ExtensionIteratorBase::ExtensionIteratorBase( Reference< XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : m_xContext( xContext ) + , m_rDatabases( rDatabases ) + , m_eState( INITIAL_MODULE ) + , m_aInitialModule( aInitialModule ) + , m_aLanguage( aLanguage ) +{ + init(); +} + +ExtensionIteratorBase::ExtensionIteratorBase( Databases& rDatabases, + const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : m_rDatabases( rDatabases ) + , m_eState( INITIAL_MODULE ) + , m_aInitialModule( aInitialModule ) + , m_aLanguage( aLanguage ) +{ + init(); +} + +void ExtensionIteratorBase::init() +{ + if( !m_xContext.is() ) + { + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext; + OSL_ASSERT( m_xContext.is() ); + } + } + if( !m_xContext.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ), + Reference< XInterface >() ); + } + + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + m_xSFA = Reference< ucb::XSimpleFileAccess >( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), + m_xContext ), UNO_QUERY_THROW ); + + m_bUserPackagesLoaded = false; + m_bSharedPackagesLoaded = false; + m_bBundledPackagesLoaded = false; + m_iUserPackage = 0; + m_iSharedPackage = 0; + m_iBundledPackage = 0; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage + ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + o_xParentPackageBundle.clear(); + + Reference< deployment::XPackage > xHelpPackage; + if( !xPackage.is() ) + return xHelpPackage; + + // #i84550 Cache information about help content in extension + rtl::OUString aExtensionPath = xPackage->getURL(); + ExtensionHelpExistanceMap::iterator it = aHelpExistanceMap.find( aExtensionPath ); + bool bFound = ( it != aHelpExistanceMap.end() ); + bool bHasHelp = bFound ? it->second : false; + if( bFound && !bHasHelp ) + return xHelpPackage; + + // Check if parent package is registered + beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered + ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) ); + bool bRegistered = false; + if( option.IsPresent ) + { + beans::Ambiguous<sal_Bool> const & reg = option.Value; + if( !reg.IsAmbiguous && reg.Value ) + bRegistered = true; + } + if( bRegistered ) + { + if( xPackage->isBundle() ) + { + Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle + ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ); + sal_Int32 nPkgCount = aPkgSeq.getLength(); + const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray(); + for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg ) + { + const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ]; + const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType(); + rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); + if( aMediaType.equals( aHelpMediaType ) ) + { + xHelpPackage = xSubPkg; + o_xParentPackageBundle = xPackage; + break; + } + } + } + else + { + const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType(); + rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); + if( aMediaType.equals( aHelpMediaType ) ) + xHelpPackage = xPackage; + } + } + + if( !bFound ) + aHelpExistanceMap[ aExtensionPath ] = xHelpPackage.is(); + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bUserPackagesLoaded ) + { + Reference< XExtensionManager > xExtensionManager = ExtensionManager::get(m_xContext); + m_aUserPackagesSeq = xExtensionManager->getDeployedExtensions + ( rtl::OUString::createFromAscii("user"), Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + m_bUserPackagesLoaded = true; + } + + if( m_iUserPackage == m_aUserPackagesSeq.getLength() ) + { + m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE + } + else + { + const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bSharedPackagesLoaded ) + { + Reference< XExtensionManager > xExtensionManager = ExtensionManager::get(m_xContext); + m_aSharedPackagesSeq = xExtensionManager->getDeployedExtensions + ( rtl::OUString::createFromAscii("shared"), Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + m_bSharedPackagesLoaded = true; + } + + if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() ) + { + m_eState = BUNDLED_EXTENSIONS; + } + else + { + const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextBundledHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bBundledPackagesLoaded ) + { + Reference< XExtensionManager > xExtensionManager = ExtensionManager::get(m_xContext); + m_aBundledPackagesSeq = xExtensionManager->getDeployedExtensions + ( rtl::OUString::createFromAscii("bundled"), Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + m_bBundledPackagesLoaded = true; + } + + if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() ) + { + m_eState = END_REACHED; + } + else + { + const Reference< deployment::XPackage >* pBundledPackages = + m_aBundledPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextBundledHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +rtl::OUString ExtensionIteratorBase::implGetFileFromPackage( + const rtl::OUString& rFileExtension, Reference< deployment::XPackage > xPackage ) +{ + // No extension -> search for pure language folder + bool bLangFolderOnly = (rFileExtension.getLength() == 0); + + rtl::OUString aFile; + rtl::OUString aLanguage = m_aLanguage; + for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass ) + { + rtl::OUStringBuffer aStrBuf; + aStrBuf.append( xPackage->getRegistrationDataURL().Value); + aStrBuf.append( aSlash ); + aStrBuf.append( aLanguage ); + if( !bLangFolderOnly ) + { + aStrBuf.append( aSlash ); + aStrBuf.append( aHelpFilesBaseName ); + aStrBuf.append( rFileExtension ); + } + + aFile = m_rDatabases.expandURL( aStrBuf.makeStringAndClear() ); + if( iPass == 0 ) + { + if( m_xSFA->exists( aFile ) ) + break; + + ::std::vector< ::rtl::OUString > av; + implGetLanguageVectorFromPackage( av, xPackage ); + ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); + try + { + pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); + } + catch( ::comphelper::Locale::MalFormedLocaleException& ) + {} + if( pFound != av.end() ) + aLanguage = *pFound; + } + } + return aFile; +} + +inline bool isLetter( sal_Unicode c ) +{ + bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); + return bLetter; +} + +void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ) +{ + rv.clear(); + rtl::OUString aExtensionPath = xPackage->getURL(); + Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true ); + + const rtl::OUString* pSeq = aEntrySeq.getConstArray(); + sal_Int32 nCount = aEntrySeq.getLength(); + for( sal_Int32 i = 0 ; i < nCount ; ++i ) + { + rtl::OUString aEntry = pSeq[i]; + if( m_xSFA->isFolder( aEntry ) ) + { + sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + { + rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 ); + + // Check language sceme + int nLen = aPureEntry.getLength(); + const sal_Unicode* pc = aPureEntry.getStr(); + bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) ); + bool bIsLanguage = bStartCanBeLanguage && + ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) ); + if( bIsLanguage ) + rv.push_back( aPureEntry ); + } + } + } +} + + +//=================================================================== +// class DataBaseIterator + +Db* DataBaseIterator::nextDb( rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath ) +{ + Db* pRetDb = NULL; + + while( !pRetDb && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + pRetDb = m_rDatabases.getBerkeley( m_aInitialModule, m_aLanguage, m_bHelpText ); + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath ); + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath ); + break; + } + + case BUNDLED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath ); + break; + } + + case END_REACHED: + VOS_ENSURE( false, "DataBaseIterator::nextDb(): Invalid case END_REACHED" ); + break; + } + } + + return pRetDb; +} + +Db* DataBaseIterator::implGetDbFromPackage( Reference< deployment::XPackage > xPackage, + rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath ) +{ + + beans::Optional< ::rtl::OUString> optRegData; + try + { + optRegData = xPackage->getRegistrationDataURL(); + } + catch ( deployment::ExtensionRemovedException&) + { + return NULL; + } + + Db* pRetDb = NULL; + if (optRegData.IsPresent && optRegData.Value.getLength() > 0) + { + rtl::OUString aRegDataUrl(optRegData.Value); + aRegDataUrl += aSlash; + + rtl::OUString aUsedLanguage = m_aLanguage; + pRetDb = m_rDatabases.getBerkeley( + aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aRegDataUrl); + + // Language fallback + if( !pRetDb ) + { + ::std::vector< ::rtl::OUString > av; + implGetLanguageVectorFromPackage( av, xPackage ); + ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); + try + { + pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); + } + catch( ::comphelper::Locale::MalFormedLocaleException& ) + {} + if( pFound != av.end() ) + { + aUsedLanguage = *pFound; + pRetDb = m_rDatabases.getBerkeley( + aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aRegDataUrl); + } + } + + if( o_pExtensionPath ) + *o_pExtensionPath = aRegDataUrl + aUsedLanguage; + + if( o_pExtensionRegistryPath ) + *o_pExtensionRegistryPath = xPackage->getURL() + aSlash + aUsedLanguage; + } + + return pRetDb; +} + + +//=================================================================== +// class KeyDataBaseFileIterator + +rtl::OUString KeyDataBaseFileIterator::nextDbFile( bool& o_rbExtension ) +{ + rtl::OUString aRetFile; + + while( !aRetFile.getLength() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + aRetFile = + m_rDatabases.getInstallPathAsSystemPath() + + m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule + + rtl::OUString::createFromAscii( ".key" ); + + o_rbExtension = false; + + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetDbFileFromPackage( xHelpPackage ); + o_rbExtension = true; + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetDbFileFromPackage( xHelpPackage ); + o_rbExtension = true; + break; + } + + case BUNDLED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetDbFileFromPackage( xHelpPackage ); + o_rbExtension = true; + break; + } + + case END_REACHED: + VOS_ENSURE( false, "DataBaseIterator::nextDbFile(): Invalid case END_REACHED" ); + break; + } + } + + return aRetFile; +} + +rtl::OUString KeyDataBaseFileIterator::implGetDbFileFromPackage + ( Reference< deployment::XPackage > xPackage ) +{ + rtl::OUString aExpandedURL = + implGetFileFromPackage( rtl::OUString::createFromAscii( ".key" ), xPackage ); + + rtl::OUString aRetFile; + osl::FileBase::getSystemPathFromFileURL( aExpandedURL, aRetFile ); + + return aRetFile; +} + + +//=================================================================== +// class JarFileIterator + +Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile + ( Reference< deployment::XPackage >& o_xParentPackageBundle, + rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath ) +{ + Reference< XHierarchicalNameAccess > xNA; + + while( !xNA.is() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + xNA = m_rDatabases.jarFile( m_aInitialModule, m_aLanguage ); + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( o_xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath ); + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( o_xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath ); + break; + } + + case BUNDLED_EXTENSIONS: + { + Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( o_xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath, o_pExtensionRegistryPath ); + break; + } + + case END_REACHED: + VOS_ENSURE( false, "JarFileIterator::nextJarFile(): Invalid case END_REACHED" ); + break; + } + } + + return xNA; +} + +Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage +( Reference< deployment::XPackage > xPackage, rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath ) +{ + Reference< XHierarchicalNameAccess > xNA; + + rtl::OUString zipFile = + implGetFileFromPackage( rtl::OUString::createFromAscii( ".jar" ), xPackage ); + + try + { + Sequence< Any > aArguments( 2 ); + aArguments[ 0 ] <<= zipFile; + + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + + Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + Reference< XInterface > xIfc + = xSMgr->createInstanceWithArgumentsAndContext( + rtl::OUString::createFromAscii( + "com.sun.star.packages.comp.ZipPackage" ), + aArguments, m_xContext ); + + if ( xIfc.is() ) + { + xNA = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY ); + + VOS_ENSURE( xNA.is(), + "JarFileIterator::implGetJarFromPackage() - " + "Got no hierarchical name access!" ); + } + } + catch ( RuntimeException & ) + {} + catch ( Exception & ) + {} + + if( xNA.is() && o_pExtensionPath != NULL ) + { + // Extract path including language from file name + sal_Int32 nLastSlash = zipFile.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + *o_pExtensionPath = zipFile.copy( 0, nLastSlash ); + + if( o_pExtensionRegistryPath != NULL ) + { + rtl::OUString& rPath = *o_pExtensionPath; + sal_Int32 nLastSlashInPath = rPath.lastIndexOf( '/', rPath.getLength() - 1 ); + + *o_pExtensionRegistryPath = xPackage->getURL(); + *o_pExtensionRegistryPath += rPath.copy( nLastSlashInPath); + } + } + + return xNA; +} + + +//=================================================================== +// class IndexFolderIterator + +rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary ) +{ + rtl::OUString aIndexFolder; + + while( !aIndexFolder.getLength() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + aIndexFolder = + m_rDatabases.getInstallPathAsURL() + + m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule + + rtl::OUString::createFromAscii( ".idxl" ); + + o_rbTemporary = false; + o_rbExtension = false; + + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); + o_rbExtension = true; + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); + o_rbExtension = true; + break; + } + + case BUNDLED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextBundledHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); + o_rbExtension = true; + break; + } + + case END_REACHED: + VOS_ENSURE( false, "IndexFolderIterator::nextIndexFolder(): Invalid case END_REACHED" ); + break; + } + } + + return aIndexFolder; +} + +rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( bool& o_rbTemporary, Reference< deployment::XPackage > xPackage ) +{ + rtl::OUString aIndexFolder = + implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage ); + + o_rbTemporary = false; + if( !m_xSFA->isFolder( aIndexFolder ) ) + { + // i98680: Missing index? Try to generate now + rtl::OUString aLangURL = implGetFileFromPackage( rtl::OUString(), xPackage ); + if( m_xSFA->isFolder( aLangURL ) ) + { + // Test write access (shared extension may be read only) + bool bIsWriteAccess = false; + try + { + rtl::OUString aCreateTestFolder = aLangURL + rtl::OUString::createFromAscii( "CreateTestFolder" ); + m_xSFA->createFolder( aCreateTestFolder ); + if( m_xSFA->isFolder( aCreateTestFolder ) ) + bIsWriteAccess = true; + + m_xSFA->kill( aCreateTestFolder ); + } + catch (Exception &) + {} + + // TEST + //bIsWriteAccess = false; + + Reference< script::XInvocation > xInvocation; + Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + try + { + xInvocation = Reference< script::XInvocation >( + m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.help.HelpIndexer" ), m_xContext ) , UNO_QUERY ); + + if( xInvocation.is() ) + { + Sequence<uno::Any> aParamsSeq( bIsWriteAccess ? 6 : 8 ); + + aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) ); + + rtl::OUString aLang; + sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + aLang = aLangURL.copy( nLastSlash + 1 ); + else + aLang = rtl::OUString::createFromAscii( "en" ); + aParamsSeq[1] = uno::makeAny( aLang ); + + aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) ); + aParamsSeq[3] = uno::makeAny( rtl::OUString::createFromAscii( "help" ) ); + + rtl::OUString aZipDir = aLangURL; + if( !bIsWriteAccess ) + { + rtl::OUString aTempFileURL; + ::osl::FileBase::RC eErr = ::osl::File::createTempFile( 0, 0, &aTempFileURL ); + if( eErr == ::osl::FileBase::E_None ) + { + rtl::OUString aTempDirURL = aTempFileURL; + try + { + m_xSFA->kill( aTempDirURL ); + } + catch (Exception &) + {} + m_xSFA->createFolder( aTempDirURL ); + + aZipDir = aTempDirURL; + o_rbTemporary = true; + } + } + + aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); + rtl::OUString aSystemPath; + osl::FileBase::getSystemPathFromFileURL( aZipDir, aSystemPath ); + aParamsSeq[5] = uno::makeAny( aSystemPath ); + + if( !bIsWriteAccess ) + { + aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-srcdir" ) ); + rtl::OUString aSrcDirVal; + osl::FileBase::getSystemPathFromFileURL( aLangURL, aSrcDirVal ); + aParamsSeq[7] = uno::makeAny( aSrcDirVal ); + } + + Sequence< sal_Int16 > aOutParamIndex; + Sequence< uno::Any > aOutParam; + uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ), + aParamsSeq, aOutParamIndex, aOutParam ); + + if( bIsWriteAccess ) + aIndexFolder = implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage ); + else + aIndexFolder = aZipDir + rtl::OUString::createFromAscii( "/help.idxl" ); + } + } + catch (Exception &) + {} + } + } + + return aIndexFolder; +} + +void IndexFolderIterator::deleteTempIndexFolder( const rtl::OUString& aIndexFolder ) +{ + sal_Int32 nLastSlash = aIndexFolder.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + { + rtl::OUString aTmpFolder = aIndexFolder.copy( 0, nLastSlash ); + try + { + m_xSFA->kill( aTmpFolder ); + } + catch (Exception &) + {} + } +} diff --git a/xmlhelp/source/cxxhelp/provider/databases.hxx b/xmlhelp/source/cxxhelp/provider/databases.hxx new file mode 100644 index 000000000000..aa80bf27405b --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/databases.hxx @@ -0,0 +1,560 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DATABASES_HXX_ +#define _DATABASES_HXX_ + +#ifndef INCLUDED_STL_SET +#include <set> +#define INCLUDED_STL_SET +#endif +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <hash_map> +#include <hash_set> +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/deployment/XPackage.hpp> +#include "com/sun/star/ucb/XSimpleFileAccess.hpp" + +// Forward declaration + + +namespace berkeleydbproxy { + + class Db; + +} + + +namespace chelp { + + + class Databases; + class URLParameter; + + class StaticModuleInformation + { + private: + + rtl::OUString m_aStartId; + rtl::OUString m_aProgramSwitch; + rtl::OUString m_aTitle; + rtl::OUString m_aHeading; + rtl::OUString m_aFulltext; + int m_nOrder; + + + public: + + StaticModuleInformation( rtl::OUString aTitle, + rtl::OUString aStartId, + rtl::OUString aProgramSwitch, + rtl::OUString aHeading, + rtl::OUString aFulltext, + rtl::OUString aOrder ) + : m_aStartId( aStartId ), + m_aProgramSwitch( aProgramSwitch ), + m_aTitle( aTitle ), + m_aHeading( aHeading ), + m_aFulltext( aFulltext ), + m_nOrder( aOrder.toInt32() ) + { + } + + ~StaticModuleInformation() { } + + rtl::OUString get_title() { return m_aTitle; } + rtl::OUString get_id() { return m_aStartId; } + rtl::OUString get_program() { return m_aProgramSwitch; } + rtl::OUString get_heading() { return m_aHeading; } + rtl::OUString get_fulltext() { return m_aFulltext; } + int get_order() { return m_nOrder; } + }; // end class StaticModuleInformation + + + + class KeywordInfo + { + public: + + class KeywordElement + { + friend struct KeywordElementComparator; + friend class KeywordInfo; + + public: + + KeywordElement( Databases* pDatabases, + berkeleydbproxy::Db* pDb, + rtl::OUString& key, + rtl::OUString& ids ); + + private: + + rtl::OUString key; + com::sun::star::uno::Sequence< rtl::OUString > listId; + com::sun::star::uno::Sequence< rtl::OUString > listAnchor; + com::sun::star::uno::Sequence< rtl::OUString > listTitle; + + void init( Databases *pDatabases,berkeleydbproxy::Db* pDb,const rtl::OUString& ids ); + }; + + + KeywordInfo( const std::vector< KeywordElement >& aVector ); + + ~KeywordInfo() { }; + + com::sun::star::uno::Sequence< rtl::OUString >& + getKeywordList() { return listKey; } + + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >& + getIdList() { return listId; } + + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >& + getAnchorList() { return listAnchor; } + + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >& + getTitleList() { return listTitle; } + + private: + + com::sun::star::uno::Sequence< rtl::OUString > listKey; + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > > listId,listAnchor,listTitle; + }; // end class KeywordInfo + + + + class Databases + { + public: + + struct eq + { + bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const + { + return rKey1.compareTo( rKey2 ) == 0; + } + }; + + struct ha + { + size_t operator()( const rtl::OUString& rName ) const + { + return rName.hashCode(); + } + }; + + + /** + * Input is the installdirectory in system dependent notation + */ + + Databases( sal_Bool showBasic, + const rtl::OUString& instPath, + const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths, + const rtl::OUString& productName, + const rtl::OUString& productVersion, + const rtl::OUString& styleSheet, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext ); + + ~Databases(); + + rtl::OString getImagesZipFileURL(); + + rtl::OUString getInstallPathAsSystemPath(); + + rtl::OUString getInstallPathAsURL(); + + const std::vector< rtl::OUString >& getModuleList( const rtl::OUString& Language ); + + StaticModuleInformation* getStaticInformationForModule( const rtl::OUString& Module, + const rtl::OUString& Language ); + + bool checkModuleMatchForExtension( const rtl::OUString& Database, const rtl::OUString& doclist ); + KeywordInfo* getKeyword( const rtl::OUString& Module, + const rtl::OUString& Language ); + + berkeleydbproxy::Db* getBerkeley( const rtl::OUString& Module, + const rtl::OUString& Language, bool helpText = false, + const rtl::OUString* pExtensionPath = NULL ); + + + /** + * The following method returns the Collator for the given language-country combination + */ + + com::sun::star::uno::Reference< com::sun::star::i18n::XCollator > + getCollator( const rtl::OUString& Language, + const rtl::OUString& System ); // System not used by current implementation + // // of XCollator + + /** + * Returns a copy of the popupfile + */ + + void popupDocument( URLParameter* urlPar,char **buffer,int *byteCount ); + + + /** + * Returns the cascading stlye sheet used to format the HTML-output. + * First try is language directory, second try is main installation directory. + */ + + void cascadingStylesheet( const rtl::OUString& Language, + char** buffer, + int* byteCount ); + + + /** + * Changes the the stylesheet for further reads. + */ + + void changeCSS(const rtl::OUString& newStyleSheet); + + + /** + * Returns the active help text for the given module, language and id. + */ + + void setActiveText( const rtl::OUString& Module, + const rtl::OUString& Language, + const rtl::OUString& Id, + char** buffer, + int* byteCount ); + + /** + * Has the purpose of forcing the the jarfile to stay open + */ + + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + jarFile( const rtl::OUString& jar, + const rtl::OUString& Language ); + + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + findJarFileForPath( const rtl::OUString& jar, const rtl::OUString& Language, + const rtl::OUString& path, rtl::OUString* o_pExtensionPath = NULL, + rtl::OUString* o_pExtensionRegistryPath = NULL ); + + /** + * Maps a given language-locale combination to language. + */ + + rtl::OUString processLang( const rtl::OUString& Language ); + + + /** + * Maps a given language-locale combination to locale. + * The returned string maybe empty + */ + + rtl::OUString country( const rtl::OUString& Language ); + + + void replaceName( rtl::OUString& oustring ) const; + + rtl::OUString getProductName() const { return m_vReplacement[0]; } + rtl::OUString getProductVersion() const { return m_vReplacement[1]; } + + rtl::OUString expandURL( const rtl::OUString& aURL ); + + static rtl::OUString expandURL( const rtl::OUString& aURL, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext ); + + private: + + osl::Mutex m_aMutex; + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext; + com::sun::star::uno::Reference< com::sun::star::lang::XMultiComponentFactory > m_xSMgr; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA; + + sal_Bool m_bShowBasic; + int m_nErrorDocLength; + char* m_pErrorDoc; + + int m_nCustomCSSDocLength; + char* m_pCustomCSSDoc; + rtl::OUString m_aCSS; + +#define PRODUCTNAME 0 +#define PRODUCTVERSION 1 +#define VENDORNAME 2 +#define VENDORVERSION 3 +#define VENDORSHORT 4 +#define NEWPRODUCTNAME 5 +#define NEWPRODUCTVERSION 6 + + int m_vAdd[7]; + rtl::OUString m_vReplacement[7]; + rtl::OUString newProdName,newProdVersion, + prodName,prodVersion,vendName,vendVersion,vendShort; + + rtl::OUString m_aInstallDirectory; // Installation directory + com::sun::star::uno::Sequence< rtl::OUString > m_aImagesZipPaths; + rtl::OString m_aImagesZipFileURL; + sal_Int16 m_nSymbolsStyle; + rtl::OUString m_aInstallDirectoryWithoutEncoding; // a work around for a Sablot bug. + rtl::OUString m_aInstallDirectoryAsSystemPath; // Installation directory + + std::vector< rtl::OUString > m_avModules; + + typedef std::hash_map< rtl::OUString,berkeleydbproxy::Db*,ha,eq > DatabasesTable; + DatabasesTable m_aDatabases; // Language and module dependent databases + + typedef std::hash_map< rtl::OUString,rtl::OUString,ha,eq > LangSetTable; + LangSetTable m_aLangSet; // Mapping to of lang-country to lang + + typedef std::hash_map< rtl::OUString,StaticModuleInformation*,ha,eq > ModInfoTable; + ModInfoTable m_aModInfo; // Module information + + typedef std::hash_map< rtl::OUString,KeywordInfo*,ha,eq > KeywordInfoTable; + KeywordInfoTable m_aKeywordInfo; // Module information + + typedef + std::hash_map< + rtl::OUString, + ::com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >, + ha, + eq > ZipFileTable; + ZipFileTable m_aZipFileTable; // No closing of an once opened jarfile + + typedef + std::hash_map< + rtl::OUString, + ::com::sun::star::uno::Reference< com::sun::star::i18n::XCollator >, + ha, + eq > CollatorTable; + CollatorTable m_aCollatorTable; + + + struct ostring_eq + { + bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const + { + return rKey1.compareTo( rKey2 ) == 0; + } + }; + + struct ostring_ha + { + size_t operator()( const rtl::OString& rName ) const + { + return rName.hashCode(); + } + }; + + typedef + std::hash_set< + rtl::OString, + ostring_ha, + ostring_eq > EmptyActiveTextSet; + EmptyActiveTextSet m_aEmptyActiveTextSet; + + + // methods + + void setInstallPath( const rtl::OUString& aInstallDirectory ); + + }; // end class Databases + + + //=================================================================== + enum IteratorState + { + INITIAL_MODULE, + //SHARED_MODULE, // Later, avoids redundancies in help compiling + USER_EXTENSIONS, + SHARED_EXTENSIONS, + BUNDLED_EXTENSIONS, + END_REACHED + }; + + // Hashtable to cache extension help status + typedef std::hash_map + < + ::rtl::OUString, + bool, + Databases::ha, + Databases::eq + > + ExtensionHelpExistanceMap; + + + class ExtensionIteratorBase + { + static ExtensionHelpExistanceMap aHelpExistanceMap; + + public: + ExtensionIteratorBase( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ); + ExtensionIteratorBase( Databases& rDatabases, const rtl::OUString& aInitialModule, + const rtl::OUString& aLanguage ); + void init( void ); + + private: + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetHelpPackageFromPackage + ( const com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + + protected: + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextUserHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextSharedHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextBundledHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + rtl::OUString implGetFileFromPackage( const rtl::OUString& rFileExtension, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + void implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA; + Databases& m_rDatabases; + + IteratorState m_eState; + rtl::OUString m_aExtensionPath; + + rtl::OUString m_aInitialModule; + rtl::OUString m_aLanguage; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aUserPackagesSeq; + bool m_bUserPackagesLoaded; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aSharedPackagesSeq; + bool m_bSharedPackagesLoaded; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aBundledPackagesSeq; + bool m_bBundledPackagesLoaded; + + int m_iUserPackage; + int m_iSharedPackage; + int m_iBundledPackage; + + }; // end class ExtensionIteratorBase + + + //=================================================================== + class DataBaseIterator : public ExtensionIteratorBase + { + public: + DataBaseIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage, bool bHelpText ) + : ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage ) + , m_bHelpText( bHelpText ) + {} + DataBaseIterator( Databases& rDatabases, const rtl::OUString& aInitialModule, + const rtl::OUString& aLanguage, bool bHelpText ) + : ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage ) + , m_bHelpText( bHelpText ) + {} + + berkeleydbproxy::Db* nextDb( rtl::OUString* o_pExtensionPath = NULL, rtl::OUString* o_pExtensionRegistryPath = NULL ); + + + private: + berkeleydbproxy::Db* implGetDbFromPackage( + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + rtl::OUString* o_pExtensionPath, rtl::OUString* o_pExtensionRegistryPath ); + + bool m_bHelpText; + + }; // end class DataBaseIterator + + //=================================================================== + class KeyDataBaseFileIterator : public ExtensionIteratorBase + { + public: + KeyDataBaseFileIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage ) + {} + + rtl::OUString nextDbFile( bool& o_rbExtension ); + + private: + rtl::OUString implGetDbFileFromPackage( + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + }; // end class KeyDataBaseFileIterator + + //=================================================================== + class JarFileIterator : public ExtensionIteratorBase + { + public: + JarFileIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage ) + {} + + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + nextJarFile( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle, + rtl::OUString* o_pExtensionPath = NULL, rtl::OUString* o_pExtensionRegistryPath = NULL ); + + private: + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + implGetJarFromPackage(com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + rtl::OUString* o_pExtensionPath = NULL, rtl::OUString* o_pExtensionRegistryPath = NULL ); + + }; // end class JarFileIterator + + //=================================================================== + class IndexFolderIterator : public ExtensionIteratorBase + { + public: + IndexFolderIterator( Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage ) + {} + + rtl::OUString nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary ); + void deleteTempIndexFolder( const rtl::OUString& aIndexFolder ); + + private: + rtl::OUString implGetIndexFolderFromPackage( bool& o_rbTemporary, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + }; // end class KeyDataBaseFileIterator + + //=================================================================== + +} // end namespace chelp + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/db.cxx b/xmlhelp/source/cxxhelp/provider/db.cxx new file mode 100644 index 000000000000..abc5acc6381c --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/db.cxx @@ -0,0 +1,664 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +#include "db.hxx" + +#include <rtl/alloc.h> +#include <cstring> + +#include "com/sun/star/io/XSeekable.hpp" + +#ifdef TEST_DBHELP +#include <osl/time.h> +#endif + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; + +namespace berkeleydbproxy { + +//---------------------------------------------------------------------------- +namespace db_internal +{ + // static void raise_error(int dberr, const char * where); + + static inline int check_error(int dberr, const char * where) + { + (void)where; + + // if (dberr) raise_error(dberr,where); + return dberr; + } +} + +void DBData::copyToBuffer( const char* pSrcData, int nSize ) +{ + m_nSize = nSize; + delete [] m_pBuffer; + m_pBuffer = new char[m_nSize+1]; + memcpy( m_pBuffer, pSrcData, m_nSize ); + m_pBuffer[m_nSize] = 0; +} + + +// DBHelp + +bool DBHelp::implReadLenAndData( const char* pData, int& riPos, DBData& rValue ) +{ + bool bSuccess = false; + + // Read key len + const char* pStartPtr = pData + riPos; + char* pEndPtr; + sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 ); + if( pEndPtr == pStartPtr ) + return bSuccess; + riPos += (pEndPtr - pStartPtr) + 1; + + const char* pKeySrc = pData + riPos; + rValue.copyToBuffer( pKeySrc, nKeyLen ); + riPos += nKeyLen + 1; + + bSuccess = true; + return bSuccess; +} + +#ifdef TEST_DBHELP + +typedef std::pair< rtl::OString, rtl::OString > KeyValPair; +typedef std::vector< KeyValPair > KeyValPairVector; + +void testWriteKeyValue( FILE* pFile, const KeyValPair& rKeyValPair ) +{ + if( pFile == NULL ) + return; + char cLF = 10; + + const rtl::OString& aKeyStr = rKeyValPair.first; + const rtl::OString& aValueStr = rKeyValPair.second; + int nKeyLen = aKeyStr.getLength(); + int nValueLen = aValueStr.getLength(); + fprintf( pFile, "%x ", nKeyLen ); + if( nKeyLen > 0 ) + fwrite( aKeyStr.getStr(), 1, nKeyLen, pFile ); + fprintf( pFile, " %x ", nValueLen ); + if( nValueLen > 0 ) + fwrite( aValueStr.getStr(), 1, nValueLen, pFile ); + fprintf( pFile, "%c", cLF ); +} + +bool DBHelp::testAgainstDb( const rtl::OString& fileName, bool bOldDbAccess ) +{ + bool bSuccess = true; + + KeyValPairVector avKeyValPair; + + rtl::OString aOutFileName = fileName; + aOutFileName += "_TestOut"; + if( bOldDbAccess ) + aOutFileName += "_Old"; + FILE* pFile = fopen( aOutFileName.getStr(), "wb" ); + + // Get all values + Db table; + if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + bool first = true; + + Dbc* cursor = 0; + table.cursor( 0,&cursor,0 ); + Dbt key_,data; + key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory + data.set_flags( DB_DBT_MALLOC ); + + while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) ) + { + rtl::OString keyword( static_cast<sal_Char*>(key_.get_data()), + key_.get_size() ); + rtl::OString value( static_cast<sal_Char*>(data.get_data()), + data.get_size() ); + + KeyValPair aPair( keyword, value ); + avKeyValPair.push_back( aPair ); + if( pFile != NULL ) + testWriteKeyValue( pFile, aPair ); + + if( first ) + { + key_.set_flags( DB_DBT_REALLOC ); + data.set_flags( DB_DBT_REALLOC ); + first = false; + } + } + + if( cursor ) cursor->close(); + } + table.close( 0 ); + + // TEST + DBData aDBData; + Db tableTest; + Dbt data; + + int nOkCount = 0; + int nErrCount = 0; + + bool bTestSuccess; + const char* pTestReadData = NULL; + int nTestReadDataSize = 0; + + sal_uInt32 starttime = osl_getGlobalTimer(); + sal_uInt32 afterfirsttime = starttime; + + if( pFile != NULL ) + { + if( bOldDbAccess ) + fprintf( pFile, "\nTesting old access:\n" ); + else + fprintf( pFile, "\nTesting new access:\n" ); + } + + KeyValPairVector::const_iterator it; + bool bFirst = true; + for( it = avKeyValPair.begin() ; it != avKeyValPair.end() ; ++it ) + { + const KeyValPair& rKeyValPair = *it; + + const rtl::OString& aKeyStr = rKeyValPair.first; + const rtl::OString& aValueStr = rKeyValPair.second; + int nKeyLen = aKeyStr.getLength(); + int nValueLen = aValueStr.getLength(); + + const sal_Char* ptr = aValueStr.getStr(); + + bTestSuccess = false; + pTestReadData = NULL; + nTestReadDataSize = 0; + if( bOldDbAccess ) + { + if( bFirst ) + { + if( tableTest.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + if( pFile != NULL ) + fprintf( pFile, "Cannot open database\n" ); + + break; + } + } + + Dbt key( static_cast< void* >( const_cast< sal_Char* >( aKeyStr.getStr() ) ), aKeyStr.getLength() ); + int err = tableTest.get( 0, &key, &data, 0 ); + if( err == 0 ) + { + bTestSuccess = true; + pTestReadData = static_cast< sal_Char* >( data.get_data() ); + nTestReadDataSize = data.get_size(); + } + } + else + { + bTestSuccess = getValueForKey( aKeyStr, aDBData ); + if( bTestSuccess ) + { + pTestReadData = aDBData.getData(); + nTestReadDataSize = aDBData.getSize(); + } + } + if( bFirst ) + { + afterfirsttime = osl_getGlobalTimer(); + bFirst = false; + } + int nError = 0; + if( bTestSuccess && pTestReadData != NULL ) + { + int nCmp = memcmp( ptr, pTestReadData, nValueLen ); + if( nCmp == 0 ) + ++nOkCount; + else + nError = 1; + + if( nValueLen != nTestReadDataSize ) + nError = 2; + } + else + nError = 3; + + if( nError != 0 ) + { + bSuccess = false; + ++nErrCount; + + if( pFile != NULL ) + { + fprintf( pFile, "ERROR, not found:\n" ); + testWriteKeyValue( pFile, rKeyValPair ); + fprintf( pFile, "\nError Code: %d\n", nError ); + } + } + } + tableTest.close( 0 ); + + sal_uInt32 endtime = osl_getGlobalTimer(); + double dDiffTime = (endtime-starttime) / 1000.0; + double dDiffFirstTime = (afterfirsttime-starttime) / 1000.0; + if( pFile != NULL ) + { + int nCount = avKeyValPair.size(); + fprintf( pFile, "%d key/values in total, read %d correctly, %d errors\n", + nCount, nOkCount, nErrCount ); + fprintf( pFile, "Time taken: %g s (First access %g s)\n", dDiffTime, dDiffFirstTime ); + fprintf( pFile, "Average time per access: %g s\n", dDiffTime / nCount ); + } + + if( pFile != NULL ) + fclose( pFile ); + + return bSuccess; +} + +#endif + + +void DBHelp::createHashMap( bool bOptimizeForPerformance ) +{ + releaseHashMap(); + if( bOptimizeForPerformance ) + { + if( m_pStringToDataMap != NULL ) + return; + m_pStringToDataMap = new StringToDataMap(); + } + else + { + if( m_pStringToValPosMap != NULL ) + return; + m_pStringToValPosMap = new StringToValPosMap(); + } + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName ); + if( xIn.is() ) + { + Sequence< sal_Int8 > aData; + sal_Int32 nSize = m_xSFA->getSize( m_aFileName ); + sal_Int32 nRead = xIn->readBytes( aData, nSize ); + + const char* pData = (const char*)aData.getConstArray(); + int iPos = 0; + while( iPos < nRead ) + { + DBData aDBKey; + if( !implReadLenAndData( pData, iPos, aDBKey ) ) + break; + + rtl::OString aOKeyStr = aDBKey.getData(); + + // Read val len + const char* pStartPtr = pData + iPos; + char* pEndPtr; + sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 ); + if( pEndPtr == pStartPtr ) + break; + + iPos += (pEndPtr - pStartPtr) + 1; + + if( bOptimizeForPerformance ) + { + const char* pValSrc = pData + iPos; + rtl::OString aValStr( pValSrc, nValLen ); + (*m_pStringToDataMap)[aOKeyStr] = aValStr; + } + else + { + // store value start position + (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen ); + } + iPos += nValLen + 1; + } + + xIn->closeInput(); + } +} + +void DBHelp::releaseHashMap( void ) +{ + if( m_pStringToDataMap != NULL ) + { + delete m_pStringToDataMap; + m_pStringToDataMap = NULL; + } + if( m_pStringToValPosMap != NULL ) + { + delete m_pStringToValPosMap; + m_pStringToValPosMap = NULL; + } +} + + +bool DBHelp::getValueForKey( const rtl::OString& rKey, DBData& rValue ) +{ + bool bSuccess = false; + if( !m_xSFA.is() ) + return bSuccess; + + try + { + + if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL ) + { + bool bOptimizeForPerformance = false; + createHashMap( bOptimizeForPerformance ); + } + + if( m_pStringToValPosMap != NULL ) + { + StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey ); + if( it != m_pStringToValPosMap->end() ) + { + const std::pair<int,int>& rValPair = it->second; + int iValuePos = rValPair.first; + int nValueLen = rValPair.second; + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName ); + if( xIn.is() ) + { + Reference< XSeekable > xXSeekable( xIn, UNO_QUERY ); + if( xXSeekable.is() ) + { + xXSeekable->seek( iValuePos ); + + Sequence< sal_Int8 > aData; + sal_Int32 nRead = xIn->readBytes( aData, nValueLen ); + if( nRead == nValueLen ) + { + const char* pData = (const sal_Char*)aData.getConstArray(); + rValue.copyToBuffer( pData, nValueLen ); + bSuccess = true; + } + } + xIn->closeInput(); + } + } + } + + else if( m_pStringToDataMap != NULL ) + { + StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey ); + if( it != m_pStringToDataMap->end() ) + { + const rtl::OString& rValueStr = it->second; + int nValueLen = rValueStr.getLength(); + const char* pData = rValueStr.getStr(); + rValue.copyToBuffer( pData, nValueLen ); + bSuccess = true; + } + } + + } + catch( Exception & ) + { + bSuccess = false; + } + + return bSuccess; +} + +bool DBHelp::startIteration( void ) +{ + bool bSuccess = false; + + sal_Int32 nSize = m_xSFA->getSize( m_aFileName ); + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName ); + if( xIn.is() ) + { + m_nItRead = xIn->readBytes( m_aItData, nSize ); + if( m_nItRead == nSize ) + { + bSuccess = true; + m_pItData = (const char*)m_aItData.getConstArray(); + m_iItPos = 0; + } + else + { + stopIteration(); + } + } + + return bSuccess; +} + +bool DBHelp::getNextKeyAndValue( DBData& rKey, DBData& rValue ) +{ + bool bSuccess = false; + + if( m_iItPos < m_nItRead ) + { + if( implReadLenAndData( m_pItData, m_iItPos, rKey ) ) + { + if( implReadLenAndData( m_pItData, m_iItPos, rValue ) ) + bSuccess = true; + } + } + + return bSuccess; +} + +void DBHelp::stopIteration( void ) +{ + m_aItData = Sequence<sal_Int8>(); + m_pItData = NULL; + m_nItRead = -1; + m_iItPos = -1; +} + + +Db::Db() +{ + db_internal::check_error( db_create(&m_pDBP,0,0),"Db::Db" ); + m_pDBHelp = NULL; +} + + +Db::~Db() +{ + if (m_pDBP) + { + // should not happen + // TODO: add assert + } + + delete m_pDBHelp; +} + + +int Db::close(u_int32_t flags) +{ + int error = m_pDBP->close(m_pDBP,flags); + m_pDBP = 0; + return db_internal::check_error(error,"Db::close"); +} + +int Db::open(DB_TXN *txnid, + const char *file, + const char *database, + DBTYPE type, + u_int32_t flags, + int mode) +{ + int err = m_pDBP->open(m_pDBP,txnid,file,database,type,flags,mode); + return db_internal::check_error( err,"Db::open" ); +} + + +int Db::get(DB_TXN *txnid, Dbt *key, Dbt *data, u_int32_t flags) +{ + int err = m_pDBP->get(m_pDBP,txnid,key,data,flags); + + // these are non-exceptional outcomes + if (err != DB_NOTFOUND && err != DB_KEYEMPTY) + db_internal::check_error( err,"Db::get" ); + + return err; +} + +int Db::cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags) +{ + DBC * dbc = 0; + int error = m_pDBP->cursor(m_pDBP,txnid,&dbc,flags); + + if (!db_internal::check_error(error,"Db::cursor")) + *cursorp = new Dbc(dbc); + + return error; +} + +//---------------------------------------------------------------------------- + +Dbc::Dbc(DBC * dbc) +: m_pDBC(dbc) +{ +} + +Dbc::~Dbc() +{ +} + +int Dbc::close() +{ + int err = m_pDBC->c_close(m_pDBC); + delete this; + return db_internal::check_error( err,"Dbcursor::close" ); +} + +int Dbc::get(Dbt *key, Dbt *data, u_int32_t flags) +{ + int err = m_pDBC->c_get(m_pDBC,key,data,flags); + + // these are non-exceptional outcomes + if (err != DB_NOTFOUND && err != DB_KEYEMPTY) + db_internal::check_error( err, "Dbcursor::get" ); + + return err; +} + +//---------------------------------------------------------------------------- + + +Dbt::Dbt() +{ + using namespace std; + DBT * thispod = this; + memset(thispod, 0, sizeof *thispod); +} + + +Dbt::Dbt(void *data_arg, u_int32_t size_arg) +{ + using namespace std; + DBT * thispod = this; + memset(thispod, 0, sizeof *thispod); + this->set_data(data_arg); + this->set_size(size_arg); +} + +/* +Dbt::Dbt(const Dbt & other) +{ + using namespace std; + const DBT *otherpod = &other; + DBT *thispod = this; + memcpy(thispod, otherpod, sizeof *thispod); +} + +Dbt& Dbt::operator = (const Dbt & other) +{ + if (this != &other) + { + using namespace std; + const DBT *otherpod = &other; + DBT *thispod = this; + memcpy(thispod, otherpod, sizeof *thispod); + } + return *this; +} +*/ + +Dbt::~Dbt() +{ +} + +void * Dbt::get_data() const +{ + return this->data; +} + +void Dbt::set_data(void *value) +{ + this->data = value; +} + +u_int32_t Dbt::get_size() const +{ + return this->size; +} + +void Dbt::set_size(u_int32_t value) +{ + this->size = value; +} + +void Dbt::set_flags(u_int32_t value) +{ + this->flags = value; +} + +//---------------------------------------------------------------------------- +/* +void db_internal::raise_error(int dberr, const char * where) +{ + if (!where) where = "<unknown>"; + + const char * dberrmsg = db_strerror(dberr); + if (!dberrmsg || !*dberrmsg) dberrmsg = "<unknown DB error>"; + + rtl::OString msg = where; + msg += ": "; + msg += dberrmsg; + + throw DbException(msg); +} +*/ + +//---------------------------------------------------------------------------- +} // namespace ecomp + diff --git a/xmlhelp/source/cxxhelp/provider/db.hxx b/xmlhelp/source/cxxhelp/provider/db.hxx new file mode 100644 index 000000000000..eb867c0426d3 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/db.hxx @@ -0,0 +1,250 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef BERKELEYDBPROXY_DB_HXX_ +#define BERKELEYDBPROXY_DB_HXX_ + +#ifdef SYSTEM_DB +#include <db.h> +#else +#include <berkeleydb/db.h> +#endif + +#include "com/sun/star/ucb/XSimpleFileAccess.hpp" + +#include <hash_map> +#include <rtl/string.hxx> + +extern "C" { + typedef void *(*db_malloc_fcn_type)(size_t); + typedef void *(*db_realloc_fcn_type)(void *, size_t); + typedef void (*db_free_fcn_type)(void *); +} + + +namespace berkeleydbproxy { + + class Dbc; + class Dbt; + + namespace db_internal + { + class Noncopyable + { + // not implemented + Noncopyable(const Noncopyable&); + void operator=(const Noncopyable&); + protected: + Noncopyable() {} + ~Noncopyable() {} + }; + } + + class DbException + { + rtl::OString what_; + public: + explicit DbException(rtl::OString const & whatparam) + : what_(whatparam) + {} + + const char *what() const + { return what_.getStr(); } + }; + + struct eq + { + bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const + { return rKey1.compareTo( rKey2 ) == 0; } + }; + + struct ha + { + size_t operator()( const rtl::OString& rName ) const + { return rName.hashCode(); } + }; + + +//#define TEST_DBHELP + + class DBData + { + friend class DBHelp; + + int m_nSize; + char* m_pBuffer; + + void copyToBuffer( const char* pSrcData, int nSize ); + + public: + DBData( void ) + : m_nSize( 0 ) + , m_pBuffer( NULL ) + {} + ~DBData() + { delete [] m_pBuffer; } + + int getSize() const + { return m_nSize; } + const char* getData() const + { return m_pBuffer; } + }; + + typedef std::hash_map< rtl::OString,std::pair<int,int>,ha,eq > StringToValPosMap; + typedef std::hash_map< rtl::OString,rtl::OString,ha,eq > StringToDataMap; + + class DBHelp + { + rtl::OUString m_aFileName; + StringToDataMap* m_pStringToDataMap; + StringToValPosMap* m_pStringToValPosMap; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > + m_xSFA; + + com::sun::star::uno::Sequence< sal_Int8 > + m_aItData; + const char* m_pItData; + int m_nItRead; + int m_iItPos; + + bool implReadLenAndData( const char* pData, int& riPos, DBData& rValue ); + + public: + DBHelp( const rtl::OUString& rFileName, + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > xSFA ) + : m_aFileName( rFileName ) + , m_pStringToDataMap( NULL ) + , m_pStringToValPosMap( NULL ) + , m_xSFA( xSFA ) + , m_pItData( NULL ) + , m_nItRead( -1 ) + , m_iItPos( -1 ) + {} + ~DBHelp() + { releaseHashMap(); } + + void createHashMap( bool bOptimizeForPerformance = false ); + void releaseHashMap( void ); + +#ifdef TEST_DBHELP + bool testAgainstDb( const rtl::OString& fileName, bool bOldDbAccess ); +#endif + + bool getValueForKey( const rtl::OString& rKey, DBData& rValue ); + + bool startIteration( void ); + bool getNextKeyAndValue( DBData& rKey, DBData& rValue ); + void stopIteration( void ); + }; + + class Db : db_internal::Noncopyable + { + private: + DB* m_pDBP; + DBHelp* m_pDBHelp; + + public: + Db(); + ~Db(); + + void setDBHelp( DBHelp* pDBHelp ) + { m_pDBHelp = pDBHelp; } + DBHelp* getDBHelp( void ) + { return m_pDBHelp; } + + int close(u_int32_t flags); + + int open(DB_TXN *txnid, + const char *file, + const char *database, + DBTYPE type, + u_int32_t flags, + int mode); + + + int get(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags); + + int cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags); + }; + + class Dbc : db_internal::Noncopyable + { + friend class Db; + friend class Dbt; + + private: + DBC* m_pDBC; + + explicit Dbc(DBC* pDBC); + ~Dbc(); + + public: + int close(); + + int get(Dbt *key, Dbt *data, u_int32_t flags); + }; + + class Dbt: private DBT + { + friend class Db; + friend class Dbc; + + public: + Dbt(void *data_arg, u_int32_t size_arg); + + Dbt(); + //Dbt(const Dbt & other); + //Dbt & operator=(const Dbt & other); + + ~Dbt(); + + void *get_data() const; + void set_data(void *value); + + u_int32_t get_size() const; + void set_size(u_int32_t value); + + void set_flags(u_int32_t); + }; +} + +#endif + + + + + + + + + + + + + + + + diff --git a/xmlhelp/source/cxxhelp/provider/inputstream.cxx b/xmlhelp/source/cxxhelp/provider/inputstream.cxx new file mode 100644 index 000000000000..7ff2202497be --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/inputstream.cxx @@ -0,0 +1,223 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include "inputstream.hxx" + + +using namespace chelp; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + + +XInputStream_impl::XInputStream_impl( const rtl::OUString& aUncPath ) + : m_bIsOpen( false ), + m_aFile( aUncPath ) +{ + m_bIsOpen = ( osl::FileBase::E_None == m_aFile.open( OpenFlag_Read ) ); +} + + +XInputStream_impl::~XInputStream_impl() +{ + closeInput(); +} + + +bool SAL_CALL XInputStream_impl::CtorSuccess() +{ + return m_bIsOpen; +}; + + +uno::Any SAL_CALL +XInputStream_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( io::XInputStream*,this ), + SAL_STATIC_CAST( io::XSeekable*,this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL +XInputStream_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XInputStream_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL +XInputStream_impl::readBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + if( ! m_bIsOpen ) + throw io::IOException(); + + aData.realloc(nBytesToRead); + //TODO! translate memory exhaustion (if it were detectable...) into + // io::BufferSizeExceededException + + sal_uInt64 nrc; + m_aFile.read( aData.getArray(),sal_uInt64(nBytesToRead),nrc ); + + // Shrink aData in case we read less than nBytesToRead (XInputStream + // documentation does not tell whether this is required, and I do not know + // if any code relies on this, so be conservative---SB): + if (nrc != sal::static_int_cast<sal_uInt64>( nBytesToRead) ) + aData.realloc(sal_Int32(nrc)); + return ( sal_Int32 ) nrc; +} + +sal_Int32 SAL_CALL +XInputStream_impl::readSomeBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + return readBytes( aData,nMaxBytesToRead ); +} + + +void SAL_CALL +XInputStream_impl::skipBytes( + sal_Int32 nBytesToSkip ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) ); +} + + +sal_Int32 SAL_CALL +XInputStream_impl::available( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException) +{ + return 0; +} + + +void SAL_CALL +XInputStream_impl::closeInput( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + if( m_bIsOpen ) + { + osl::FileBase::RC err = m_aFile.close(); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + m_bIsOpen = false; + } +} + + +void SAL_CALL +XInputStream_impl::seek( + sal_Int64 location ) + throw( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + if( location < 0 ) + throw lang::IllegalArgumentException(); + if( osl::FileBase::E_None != m_aFile.setPos( Pos_Absolut, sal_uInt64( location ) ) ) + throw io::IOException(); +} + + +sal_Int64 SAL_CALL +XInputStream_impl::getPosition( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + sal_uInt64 uPos; + if( osl::FileBase::E_None != m_aFile.getPos( uPos ) ) + throw io::IOException(); + return sal_Int64( uPos ); +} + +sal_Int64 SAL_CALL +XInputStream_impl::getLength( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + osl::FileBase::RC err; + sal_uInt64 uCurrentPos, uEndPos; + + err = m_aFile.getPos( uCurrentPos ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + + err = m_aFile.setPos( Pos_End, 0 ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + + err = m_aFile.getPos( uEndPos ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + + err = m_aFile.setPos( Pos_Absolut, uCurrentPos ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + else + return sal_Int64( uEndPos ); +} diff --git a/xmlhelp/source/cxxhelp/provider/inputstream.hxx b/xmlhelp/source/cxxhelp/provider/inputstream.hxx new file mode 100644 index 000000000000..0494e7910c2d --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/inputstream.hxx @@ -0,0 +1,144 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _INPUSTREAM_HXX_ +#define _INPUSTREAM_HXX_ + +#include <rtl/ustring.hxx> +#include <osl/file.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> + + +namespace chelp { + + // forward declaration + + class XInputStream_impl + : public cppu::OWeakObject, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XSeekable + { + public: + + XInputStream_impl( const rtl::OUString& aUncPath ); + + virtual ~XInputStream_impl(); + + /** + * Returns an error code as given by filerror.hxx + */ + + bool SAL_CALL CtorSuccess(); + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + virtual sal_Int32 SAL_CALL + readBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + readSomeBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + skipBytes( + sal_Int32 nBytesToSkip ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL + available( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + closeInput( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + seek( + sal_Int64 location ) + throw( com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getPosition( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getLength( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + private: + + bool m_bIsOpen; + osl::File m_aFile; + }; + + +} // end namespace XInputStream_impl + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/makefile.mk b/xmlhelp/source/cxxhelp/provider/makefile.mk new file mode 100644 index 000000000000..38f57c63e705 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/makefile.mk @@ -0,0 +1,97 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=xmlhelp +TARGET=chelp + +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + + +# --- Settings --------------------------------------------------------- + +.INCLUDE: settings.mk + +# GCC versions 4.2.x introduced a warning "allocating zero-element array" +# Allocating zero-element arrays is an allowed if not somewhat dubious +# technique though, so this warning is plain wrong and has been fixed +# in gcc 4.3. Unfortunately there is no way at all to suppress this warning. +# Some files in this directory use zero allocated arrays, we need to +# diable the WaE mechanism for the GCC 4.2.x series. +.IF "$(COM)"=="GCC" +.IF "$(CCNUMVER)">="000400020000" && "$(CCNUMVER)"<="000400020003" +CFLAGSWERRCXX:= +.ENDIF # "$(CCNUMVER)">="000400020000" && "$(CCNUMVER)"<="000400020003" +.ENDIF # "$(COM)"=="GCC" + +CFLAGS += -DHAVE_EXPAT_H + +.IF "$(SYSTEM_DB)" == "YES" +CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES) +.ENDIF + +.IF "$(SYSTEM_LIBXML)" == "YES" +CFLAGS+= $(LIBXML_CFLAGS) +.ELSE +LIBXMLINCDIR=external$/libxml +CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXMLINCDIR) +.ENDIF + +.IF "$(SYSTEM_LIBXSLT)" == "YES" +CFLAGS+= $(LIBXSLT_CFLAGS) +.ELSE +LIBXSLTINCDIR=external$/libxslt +CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXSLTINCDIR) +.ENDIF + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +# --- General ----------------------------------------------------- + +SLOFILES=\ + $(SLO)$/services.obj \ + $(SLO)$/provider.obj \ + $(SLO)$/content.obj \ + $(SLO)$/resultset.obj \ + $(SLO)$/resultsetbase.obj \ + $(SLO)$/resultsetforroot.obj \ + $(SLO)$/resultsetforquery.obj \ + $(SLO)$/contentcaps.obj \ + $(SLO)$/urlparameter.obj \ + $(SLO)$/inputstream.obj \ + $(SLO)$/databases.obj \ + $(SLO)$/db.obj \ + $(SLO)$/bufferedinputstream.obj + +# --- Targets ---------------------------------------------------------- + +.INCLUDE: target.mk + diff --git a/xmlhelp/source/cxxhelp/provider/provider.cxx b/xmlhelp/source/cxxhelp/provider/provider.cxx new file mode 100644 index 000000000000..c21b5aca3ba5 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/provider.cxx @@ -0,0 +1,510 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ + +#include <stdio.h> +#include <osl/file.hxx> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <ucbhelper/contentidentifier.hxx> +#include <com/sun/star/frame/XConfigManager.hpp> +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XContainer.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <rtl/bootstrap.hxx> + +#include "databases.hxx" +#include "provider.hxx" +#include "content.hxx" +#include "databases.hxx" + +using namespace com::sun::star; +using namespace chelp; + +//========================================================================= +//========================================================================= +// +// ContentProvider Implementation. +// +//========================================================================= +//========================================================================= + +ContentProvider::ContentProvider( + const uno::Reference< lang::XMultiServiceFactory >& rSMgr ) + : ::ucbhelper::ContentProviderImplHelper( rSMgr ), + isInitialized( false ), + m_aScheme( rtl::OUString::createFromAscii( MYUCP_URL_SCHEME ) ), + m_pDatabases( 0 ) +{ +} + +//========================================================================= +// virtual +ContentProvider::~ContentProvider() +{ + delete m_pDatabases; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_6( ContentProvider, + lang::XTypeProvider, + lang::XServiceInfo, + ucb::XContentProvider, + lang::XComponent, + lang::XEventListener, /* base of XContainerListener */ + container::XContainerListener); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_5( ContentProvider, + lang::XTypeProvider, + lang::XServiceInfo, + ucb::XContentProvider, + lang::XComponent, + container::XContainerListener); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +rtl::OUString SAL_CALL ContentProvider::getImplementationName() + throw( uno::RuntimeException ) +{ + return getImplementationName_Static(); +} + +rtl::OUString ContentProvider::getImplementationName_Static() +{ + return rtl::OUString::createFromAscii("CHelpContentProvider" ); +} + +sal_Bool SAL_CALL +ContentProvider::supportsService(const rtl::OUString& ServiceName ) + throw( uno::RuntimeException ) +{ + uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames(); + const rtl::OUString* pArray = aSNL.getArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + { + if( pArray[ i ] == ServiceName ) + return sal_True; + } + + return sal_False; +} + +uno::Sequence< rtl::OUString > SAL_CALL +ContentProvider::getSupportedServiceNames() + throw( uno::RuntimeException ) +{ + return getSupportedServiceNames_Static(); +} + +static uno::Reference< uno::XInterface > SAL_CALL +ContentProvider_CreateInstance( + const uno::Reference< lang::XMultiServiceFactory> & rSMgr ) + throw( uno::Exception ) +{ + lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >( + new ContentProvider( rSMgr ) ); + return uno::Reference< uno::XInterface >::query( pX ); +} + +uno::Sequence< rtl::OUString > +ContentProvider::getSupportedServiceNames_Static() +{ + uno::Sequence< rtl::OUString > aSNS( 2 ); + aSNS.getArray()[ 0 ] = + rtl::OUString::createFromAscii( + MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 ); + aSNS.getArray()[ 1 ] = + rtl::OUString::createFromAscii( + MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 ); + + return aSNS; +} + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider ); + +//========================================================================= +// +// XContentProvider methods. +// +//========================================================================= + +// virtual +uno::Reference< ucb::XContent > SAL_CALL +ContentProvider::queryContent( + const uno::Reference< ucb::XContentIdentifier >& xCanonicId ) + throw( ucb::IllegalIdentifierException, uno::RuntimeException ) +{ + if ( !xCanonicId->getContentProviderScheme() + .equalsIgnoreAsciiCase( m_aScheme ) ) + { // Wrong URL-scheme + throw ucb::IllegalIdentifierException(); + } + + { + osl::MutexGuard aGuard( m_aMutex ); + if( !isInitialized ) + init(); + } + + if( !m_pDatabases ) + throw uno::RuntimeException(); + + rtl::OUString aOUString( m_pDatabases->getInstallPathAsURL() ); + rtl::OString aOString( aOUString.getStr(), + aOUString.getLength(), + RTL_TEXTENCODING_UTF8 ); + + // Check, if a content with given id already exists... + uno::Reference< ucb::XContent > xContent + = queryExistingContent( xCanonicId ).get(); + if ( xContent.is() ) + return xContent; + + xContent = new Content( m_xSMgr, this, xCanonicId, m_pDatabases ); + + // register new content + registerNewContent( xContent ); + + // Further checks + + if ( !xContent->getIdentifier().is() ) + throw ucb::IllegalIdentifierException(); + + return xContent; +} + +void SAL_CALL +ContentProvider::dispose() + throw ( uno::RuntimeException) +{ + if(m_xContainer.is()) + { + m_xContainer->removeContainerListener(this); + m_xContainer.clear(); + } +} + +void SAL_CALL +ContentProvider::elementReplaced(const container::ContainerEvent& Event) + throw (uno::RuntimeException) +{ + if(!m_pDatabases) + return; + + rtl::OUString accessor; + Event.Accessor >>= accessor; + if(accessor.compareToAscii("HelpStyleSheet")) + return; + + rtl::OUString replacedElement,element; + Event.ReplacedElement >>= replacedElement; + Event.Element >>= element; + + if(replacedElement == element) + return; + + m_pDatabases->changeCSS(element); +} + +void ContentProvider::init() +{ + osl::MutexGuard aGuard( m_aMutex ); + + isInitialized = true; + uno::Reference< lang::XMultiServiceFactory > sProvider( + getConfiguration() ); + uno::Reference< container::XHierarchicalNameAccess > xHierAccess( + getHierAccess( sProvider, + "org.openoffice.Office.Common" ) ); + + rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) ); + if( ! instPath.getLength() ) + // try to determine path from default + instPath = rtl::OUString::createFromAscii( "$(instpath)/help" ); + // replace anything like $(instpath); + subst( instPath ); + + rtl::OUString stylesheet( getKey( xHierAccess,"Help/HelpStyleSheet" ) ); + try + { + // now adding as configuration change listener for the stylesheet + uno::Reference< container::XNameAccess> xAccess( + xHierAccess, uno::UNO_QUERY ); + if( xAccess.is() ) + { + uno::Any aAny = + xAccess->getByName( rtl::OUString::createFromAscii( "Help" ) ); + aAny >>= m_xContainer; + if( m_xContainer.is() ) + m_xContainer->addContainerListener( this ); + } + } + catch( uno::Exception const & ) + { + } + + /** + * now determing + * productname, + * productversion, + */ + + xHierAccess = getHierAccess( sProvider, "org.openoffice.Setup" ); + rtl::OUString productname( + getKey( xHierAccess,"Product/ooName" ) ); + + rtl::OUString setupversion( + getKey( xHierAccess,"Product/ooSetupVersion" ) ); + rtl::OUString setupextension; + + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProvider( + m_xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW); + + uno::Sequence < uno::Any > lParams(1); + beans::PropertyValue aParam ; + aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); + aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product"); + lParams[0] = uno::makeAny(aParam); + + // open it + uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), + lParams) ); + + uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY); + uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension")); + + aRet >>= setupextension; + } + catch ( uno::Exception& ) + { + } + + rtl::OUString productversion( + setupversion + + rtl::OUString::createFromAscii( " " ) + + setupextension ); + + uno::Sequence< rtl::OUString > aImagesZipPaths( 2 ); + xHierAccess = getHierAccess( sProvider, "org.openoffice.Office.Common" ); + + rtl::OUString aPath( getKey( xHierAccess, "Path/Current/UserConfig" ) ); + subst( aPath ); + aImagesZipPaths[ 0 ] = aPath; + + aPath = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/config")); + rtl::Bootstrap::expandMacros(aPath); + aImagesZipPaths[ 1 ] = aPath; + + uno::Reference< uno::XComponentContext > xContext; + uno::Reference< beans::XPropertySet > xProps( m_xSMgr, uno::UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext; + OSL_ASSERT( xContext.is() ); + } + + sal_Bool showBasic = getBooleanKey(xHierAccess,"Help/ShowBasic"); + m_pDatabases = new Databases( showBasic, + instPath, + aImagesZipPaths, + productname, + productversion, + stylesheet, + xContext ); +} + +uno::Reference< lang::XMultiServiceFactory > +ContentProvider::getConfiguration() const +{ + uno::Reference< lang::XMultiServiceFactory > sProvider; + if( m_xSMgr.is() ) + { + try + { + rtl::OUString sProviderService = + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider" ); + sProvider = + uno::Reference< lang::XMultiServiceFactory >( + m_xSMgr->createInstance( sProviderService ), + uno::UNO_QUERY ); + } + catch( const uno::Exception& ) + { + OSL_ENSURE( sProvider.is(), "cant instantiate configuration" ); + } + } + + return sProvider; +} + +uno::Reference< container::XHierarchicalNameAccess > +ContentProvider::getHierAccess( + const uno::Reference< lang::XMultiServiceFactory >& sProvider, + const char* file ) const +{ + uno::Reference< container::XHierarchicalNameAccess > xHierAccess; + + if( sProvider.is() ) + { + uno::Sequence< uno::Any > seq( 1 ); + rtl::OUString sReaderService( + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess" ) ); + + seq[ 0 ] <<= rtl::OUString::createFromAscii( file ); + + try + { + xHierAccess = + uno::Reference< container::XHierarchicalNameAccess >( + sProvider->createInstanceWithArguments( + sReaderService, seq ), + uno::UNO_QUERY ); + } + catch( const uno::Exception& ) + { + } + } + return xHierAccess; +} + + + +rtl::OUString +ContentProvider::getKey( + const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const +{ + rtl::OUString instPath; + if( xHierAccess.is() ) + { + uno::Any aAny; + try + { + aAny = + xHierAccess->getByHierarchicalName( + rtl::OUString::createFromAscii( key ) ); + } + catch( const container::NoSuchElementException& ) + { + } + aAny >>= instPath; + } + return instPath; +} + +sal_Bool +ContentProvider::getBooleanKey( + const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const +{ + sal_Bool ret = sal_False; + if( xHierAccess.is() ) + { + uno::Any aAny; + try + { + aAny = + xHierAccess->getByHierarchicalName( + rtl::OUString::createFromAscii( key ) ); + } + catch( const container::NoSuchElementException& ) + { + } + aAny >>= ret; + } + return ret; +} + +void ContentProvider::subst( rtl::OUString& instpath ) const +{ + uno::Reference< frame::XConfigManager > xCfgMgr; + if( m_xSMgr.is() ) + { + try + { + xCfgMgr = + uno::Reference< frame::XConfigManager >( + m_xSMgr->createInstance( + rtl::OUString::createFromAscii( + "com.sun.star.config.SpecialConfigManager" ) ), + uno::UNO_QUERY ); + } + catch( const uno::Exception&) + { + OSL_ENSURE( xCfgMgr.is(), + "cant instantiate the special config manager " ); + } + } + + OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" ); + + if( xCfgMgr.is() ) + instpath = xCfgMgr->substituteVariables( instpath ); +} diff --git a/xmlhelp/source/cxxhelp/provider/provider.hxx b/xmlhelp/source/cxxhelp/provider/provider.hxx new file mode 100644 index 000000000000..d6d717e4f768 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/provider.hxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PROVIDER_HXX +#define _PROVIDER_HXX + +#include <rtl/ustring.hxx> +#include <osl/mutex.hxx> +#include <ucbhelper/providerhelper.hxx> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/container/XContainer.hpp> +#include <com/sun/star/lang/XComponent.hpp> + + +namespace chelp { + +//========================================================================= + +// UNO service name for the provider. This name will be used by the UCB to +// create instances of the provider. + +//#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME "com.sun.star.ucb.CHelpContentProvider" +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 "com.sun.star.help.XMLHelp" +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME_LENGTH1 25 + +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 "com.sun.star.ucb.HelpContentProvider" +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME_LENGTH2 36 + +// URL scheme. This is the scheme the provider will be able to create +// contents for. The UCB will select the provider ( i.e. in order to create +// contents ) according to this scheme. + +#define MYUCP_URL_SCHEME "vnd.sun.star.help" +#define MYUCP_URL_SCHEME_LENGTH 18 +#define MYUCP_CONTENT_TYPE "application/vnd.sun.star.xmlhelp" // UCB Content Type. + +//========================================================================= + + + class Databases; + + + class ContentProvider : + public ::ucbhelper::ContentProviderImplHelper, + public ::com::sun::star::container::XContainerListener, + public ::com::sun::star::lang::XComponent + { + public: + ContentProvider( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMgr ); + + virtual ~ContentProvider(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_DECL() + + // XContentProvider + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContent > SAL_CALL + queryContent( const ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentIdentifier >& Identifier ) + throw( ::com::sun::star::ucb::IllegalIdentifierException, + ::com::sun::star::uno::RuntimeException ); + + ////////////////////////////////////////////////////////////////////// + // Additional interfaces + ////////////////////////////////////////////////////////////////////// + + // XComponent + + virtual void SAL_CALL + dispose( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)xListener; + } + + virtual void SAL_CALL + removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)aListener; + } + + // XConainerListener ( deriver from XEventListener ) + + virtual void SAL_CALL + disposing( const ::com::sun::star::lang::EventObject& Source ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)Source; + m_xContainer = com::sun::star::uno::Reference<com::sun::star::container::XContainer>(0); + } + + virtual void SAL_CALL + elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)Event; + } + + virtual void SAL_CALL + elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)Event; + } + + virtual void SAL_CALL + elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) + throw (::com::sun::star::uno::RuntimeException); + + + ////////////////////////////////////////////////////////////////////// + // Non-interface methods. + ////////////////////////////////////////////////////////////////////// + + private: + + osl::Mutex m_aMutex; + bool isInitialized; + rtl::OUString m_aScheme; + Databases* m_pDatabases; + com::sun::star::uno::Reference<com::sun::star::container::XContainer> m_xContainer; + + // private methods + + void init(); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + getConfiguration() const; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess > + getHierAccess( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& sProvider, + const char* file ) const; + + ::rtl::OUString + getKey( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const; + + sal_Bool + getBooleanKey( + const ::com::sun::star::uno::Reference< + ::com::sun::star::container::XHierarchicalNameAccess >& xHierAccess, + const char* key) const; + + void subst( rtl::OUString& instpath ) const; + }; + +} + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultset.cxx b/xmlhelp/source/cxxhelp/provider/resultset.cxx new file mode 100644 index 000000000000..c529d67761f6 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultset.cxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/sdbc/XResultSet.hpp> + +#include "resultset.hxx" +#include "resultsetfactory.hxx" + +using namespace com::sun::star::lang; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; + + +using namespace chelp; + +//========================================================================= +//========================================================================= +// +// DynamicResultSet Implementation. +// +//========================================================================= +//========================================================================= + +DynamicResultSet::DynamicResultSet( + const Reference< XMultiServiceFactory >& rxSMgr, + const vos::ORef< Content >& rxContent, + const OpenCommandArgument2& rCommand, + const Reference< XCommandEnvironment >& rxEnv, + ResultSetFactory* pFactory ) + : ResultSetImplHelper( rxSMgr, rCommand ), + m_xContent( rxContent ), + m_xEnv( rxEnv ), + m_pFactory( pFactory ) +{ +} + +DynamicResultSet::~DynamicResultSet() +{ + delete m_pFactory; +} + +//========================================================================= +// +// Non-interface methods. +// +//========================================================================= + +void DynamicResultSet::initStatic() +{ + m_xResultSet1 = Reference< XResultSet >( m_pFactory->createResultSet() ); +} + +//========================================================================= +void DynamicResultSet::initDynamic() +{ + m_xResultSet1 = Reference< XResultSet >( m_pFactory->createResultSet() ); + + m_xResultSet2 = m_xResultSet1; +} + + + + diff --git a/xmlhelp/source/cxxhelp/provider/resultset.hxx b/xmlhelp/source/cxxhelp/provider/resultset.hxx new file mode 100644 index 000000000000..db5dbc6c0736 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultset.hxx @@ -0,0 +1,67 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _RESULTSET_HXX +#define _RESULTSET_HXX + +#include <ucbhelper/resultsethelper.hxx> +#include <vos/ref.hxx> + +#include "content.hxx" + +namespace chelp { + + class ResultSetFactory; + + class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper + { + vos::ORef< Content > m_xContent; + com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment > m_xEnv; + ResultSetFactory* m_pFactory; + + private: + virtual void initStatic(); + virtual void initDynamic(); + + public: + DynamicResultSet( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const vos::ORef< Content >& rxContent, + const com::sun::star::ucb::OpenCommandArgument2& rCommand, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& rxEnv, + ResultSetFactory* pFactory ); + + ~DynamicResultSet(); + }; + +} + +#endif + diff --git a/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx b/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx new file mode 100644 index 000000000000..fde45bbfc7a9 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx @@ -0,0 +1,656 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <ucbhelper/contentidentifier.hxx> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/uno/Reference.h> +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/ucb/ListActionType.hpp> +#include <com/sun/star/ucb/XSourceInitialization.hpp> +#include <ucbhelper/resultsetmetadata.hxx> + +#include "resultsetbase.hxx" + +using namespace chelp; +using namespace com::sun::star; + +ResultSetBase::ResultSetBase( const uno::Reference< lang::XMultiServiceFactory >& xMSF, + const uno::Reference< ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort ) + : m_xMSF( xMSF ), + m_xProvider( xProvider ), + m_nRow( -1 ), + m_nWasNull( true ), + m_nOpenMode( nOpenMode ), + m_bRowCountFinal( true ), + m_sProperty( seq ), + m_sSortingInfo( seqSort ), + m_pDisposeEventListeners( 0 ), + m_pRowCountListeners( 0 ), + m_pIsFinalListeners( 0 ) +{ +} + +ResultSetBase::~ResultSetBase() +{ + delete m_pIsFinalListeners; + delete m_pRowCountListeners; + delete m_pDisposeEventListeners; +} + + +// XInterface + +void SAL_CALL +ResultSetBase::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +ResultSetBase::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +uno::Any SAL_CALL +ResultSetBase::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XComponent*, this), + SAL_STATIC_CAST( sdbc::XRow*, this), + SAL_STATIC_CAST( sdbc::XResultSet*, this), + SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this), + SAL_STATIC_CAST( beans::XPropertySet*, this ), + SAL_STATIC_CAST( ucb::XContentAccess*, this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + + +// XComponent + + +void SAL_CALL +ResultSetBase::addEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ! m_pDisposeEventListeners ) + m_pDisposeEventListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +ResultSetBase::removeEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pDisposeEventListeners ) + m_pDisposeEventListeners->removeInterface( Listener ); +} + + + +void SAL_CALL +ResultSetBase::dispose() + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + lang::EventObject aEvt; + aEvt.Source = static_cast< lang::XComponent * >( this ); + + if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) + { + m_pDisposeEventListeners->disposeAndClear( aEvt ); + } + if( m_pRowCountListeners && m_pRowCountListeners->getLength() ) + { + m_pRowCountListeners->disposeAndClear( aEvt ); + } + if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() ) + { + m_pIsFinalListeners->disposeAndClear( aEvt ); + } +} + + + +// XResultSet + +sal_Bool SAL_CALL +ResultSetBase::next( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + sal_Bool test; + m_nRow++; + if( sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + test = true; + else + test = false; + return test; +} + + +sal_Bool SAL_CALL +ResultSetBase::isBeforeFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow == -1; +} + + +sal_Bool SAL_CALL +ResultSetBase::isAfterLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size(); // Cannot happen, if m_aFolder.isOpen() +} + + +sal_Bool SAL_CALL +ResultSetBase::isFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow == 0; +} + + +sal_Bool SAL_CALL +ResultSetBase::isLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( sal::static_int_cast<sal_uInt32>( m_nRow ) == m_aItems.size() - 1 ) + return true; + else + return false; +} + + +void SAL_CALL +ResultSetBase::beforeFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + m_nRow = -1; +} + + +void SAL_CALL +ResultSetBase::afterLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + m_nRow = m_aItems.size(); +} + + +sal_Bool SAL_CALL +ResultSetBase::first( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + m_nRow = -1; + return next(); +} + + +sal_Bool SAL_CALL +ResultSetBase::last( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + m_nRow = m_aItems.size() - 1; + return true; +} + + +sal_Int32 SAL_CALL +ResultSetBase::getRow( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + // Test, whether behind last row + if( -1 == m_nRow || sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size() ) + return 0; + else + return m_nRow+1; +} + + +sal_Bool SAL_CALL ResultSetBase::absolute( sal_Int32 row ) + throw( sdbc::SQLException, uno::RuntimeException) +{ + if( row >= 0 ) + m_nRow = row - 1; + else + { + last(); + m_nRow += ( row + 1 ); + if( m_nRow < -1 ) + m_nRow = -1; + } + + return 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); +} + + + + +sal_Bool SAL_CALL +ResultSetBase::relative( + sal_Int32 row ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( isAfterLast() || isBeforeFirst() ) + throw sdbc::SQLException(); + + if( row > 0 ) + while( row-- ) + next(); + else if( row < 0 ) + while( row++ && m_nRow > -1 ) + previous(); + + return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); +} + + + +sal_Bool SAL_CALL +ResultSetBase::previous( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( sal::static_int_cast<sal_uInt32>( m_nRow ) > m_aItems.size() ) + m_nRow = m_aItems.size(); // Correct Handling of afterLast + if( 0 <= m_nRow ) -- m_nRow; + + return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); +} + + +void SAL_CALL +ResultSetBase::refreshRow( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ +} + + +sal_Bool SAL_CALL +ResultSetBase::rowUpdated( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + +sal_Bool SAL_CALL +ResultSetBase::rowInserted( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + +sal_Bool SAL_CALL +ResultSetBase::rowDeleted( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + + +uno::Reference< uno::XInterface > SAL_CALL +ResultSetBase::getStatement( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + uno::Reference< uno::XInterface > test( 0 ); + return test; +} + + +// XCloseable + +void SAL_CALL +ResultSetBase::close( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ +} + + +rtl::OUString SAL_CALL +ResultSetBase::queryContentIdentifierString( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aPath[m_nRow]; + else + return rtl::OUString(); +} + + +uno::Reference< ucb::XContentIdentifier > SAL_CALL +ResultSetBase::queryContentIdentifier( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + { + rtl::OUString url = queryContentIdentifierString(); + if( ! m_aIdents[m_nRow].is() && url.getLength() ) + m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >( + new ::ucbhelper::ContentIdentifier( m_xMSF,url ) ); + return m_aIdents[m_nRow]; + } + + return uno::Reference< ucb::XContentIdentifier >(); +} + + +uno::Reference< ucb::XContent > SAL_CALL +ResultSetBase::queryContent( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_xProvider->queryContent( queryContentIdentifier() ); + else + return uno::Reference< ucb::XContent >(); +} + + + +class XPropertySetInfoImpl + : public cppu::OWeakObject, + public beans::XPropertySetInfo +{ +public: + + XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq ) + : m_aSeq( aSeq ) + { + } + + void SAL_CALL acquire( void ) + throw() + { + OWeakObject::acquire(); + } + + + void SAL_CALL release( void ) + throw() + { + OWeakObject::release(); + } + + uno::Any SAL_CALL queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) + { + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( beans::XPropertySetInfo*, this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); + } + + uno::Sequence< beans::Property > SAL_CALL getProperties() + throw( uno::RuntimeException ) + { + return m_aSeq; + } + + beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) + throw( beans::UnknownPropertyException, + uno::RuntimeException) + { + for( int i = 0; i < m_aSeq.getLength(); ++i ) + if( aName == m_aSeq[i].Name ) + return m_aSeq[i]; + throw beans::UnknownPropertyException(); + } + + sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) + throw( uno::RuntimeException ) + { + for( int i = 0; i < m_aSeq.getLength(); ++i ) + if( Name == m_aSeq[i].Name ) + return true; + return false; + } + +private: + + uno::Sequence< beans::Property > m_aSeq; +}; + + + +// XPropertySet +uno::Reference< beans::XPropertySetInfo > SAL_CALL +ResultSetBase::getPropertySetInfo() + throw( uno::RuntimeException) +{ + uno::Sequence< beans::Property > seq(2); + seq[0].Name = rtl::OUString::createFromAscii( "RowCount" ); + seq[0].Handle = -1; + seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) ); + seq[0].Attributes = beans::PropertyAttribute::READONLY; + + seq[1].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" ); + seq[1].Handle = -1; + seq[1].Type = getCppuType( static_cast< sal_Bool* >(0) ); + seq[1].Attributes = beans::PropertyAttribute::READONLY; + + //t + return uno::Reference< beans::XPropertySetInfo > ( new XPropertySetInfoImpl( seq ) ); +} + + + +void SAL_CALL ResultSetBase::setPropertyValue( + const rtl::OUString& aPropertyName, const uno::Any& aValue ) + throw( beans::UnknownPropertyException, + beans::PropertyVetoException, + lang::IllegalArgumentException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + (void)aValue; + + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) || + aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + return; + + throw beans::UnknownPropertyException(); +} + + +uno::Any SAL_CALL ResultSetBase::getPropertyValue( + const rtl::OUString& PropertyName ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) + { + uno::Any aAny; + aAny <<= m_bRowCountFinal; + return aAny; + } + else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + { + uno::Any aAny; + sal_Int32 count = m_aItems.size(); + aAny <<= count; + return aAny; + } + else + throw beans::UnknownPropertyException(); +} + + +void SAL_CALL ResultSetBase::addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const uno::Reference< beans::XPropertyChangeListener >& xListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( ! m_pIsFinalListeners ) + m_pIsFinalListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pIsFinalListeners->addInterface( xListener ); + } + else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( ! m_pRowCountListeners ) + m_pRowCountListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + m_pRowCountListeners->addInterface( xListener ); + } + else + throw beans::UnknownPropertyException(); +} + + +void SAL_CALL ResultSetBase::removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const uno::Reference< beans::XPropertyChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) && + m_pIsFinalListeners ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_pIsFinalListeners->removeInterface( aListener ); + } + else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) && + m_pRowCountListeners ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_pRowCountListeners->removeInterface( aListener ); + } + else + throw beans::UnknownPropertyException(); +} + + +void SAL_CALL ResultSetBase::addVetoableChangeListener( + const rtl::OUString& PropertyName, + const uno::Reference< beans::XVetoableChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + (void)PropertyName; + (void)aListener; +} + + +void SAL_CALL ResultSetBase::removeVetoableChangeListener( + const rtl::OUString& PropertyName, + const uno::Reference< beans::XVetoableChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + (void)PropertyName; + (void)aListener; +} + + + +// XResultSetMetaDataSupplier +uno::Reference< sdbc::XResultSetMetaData > SAL_CALL +ResultSetBase::getMetaData( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + ::ucbhelper::ResultSetMetaData* p = + new ::ucbhelper::ResultSetMetaData( + m_xMSF, m_sProperty ); + return uno::Reference< sdbc::XResultSetMetaData >( p ); +} diff --git a/xmlhelp/source/cxxhelp/provider/resultsetbase.hxx b/xmlhelp/source/cxxhelp/provider/resultsetbase.hxx new file mode 100644 index 000000000000..43079a830acd --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetbase.hxx @@ -0,0 +1,576 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _RESULTSETBASE_HXX +#define _RESULTSETBASE_HXX + +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/sdbc/XCloseable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/Property.hpp> + + +namespace chelp { + + class ResultSetBase + : public cppu::OWeakObject, + public com::sun::star::lang::XComponent, + public com::sun::star::sdbc::XRow, + public com::sun::star::sdbc::XResultSet, + public com::sun::star::sdbc::XCloseable, + public com::sun::star::sdbc::XResultSetMetaDataSupplier, + public com::sun::star::beans::XPropertySet, + public com::sun::star::ucb::XContentAccess + { + public: + + ResultSetBase( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort ); + + virtual ~ResultSetBase(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + // XComponent + virtual void SAL_CALL + dispose( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ); + + + // XRow + virtual sal_Bool SAL_CALL + wasNull( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + m_nWasNull = m_aItems[m_nRow]->wasNull(); + else + m_nWasNull = true; + return m_nWasNull; + } + + virtual rtl::OUString SAL_CALL + getString( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getString( columnIndex ); + else + return rtl::OUString(); + } + + virtual sal_Bool SAL_CALL + getBoolean( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBoolean( columnIndex ); + else + return false; + } + + virtual sal_Int8 SAL_CALL + getByte( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getByte( columnIndex ); + else + return sal_Int8( 0 ); + } + + virtual sal_Int16 SAL_CALL + getShort( + sal_Int32 columnIndex ) + throw( + com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getShort( columnIndex ); + else + return sal_Int16( 0 ); + } + + virtual sal_Int32 SAL_CALL + getInt( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getInt( columnIndex ); + else + return sal_Int32( 0 ); + } + + virtual sal_Int64 SAL_CALL + getLong( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getLong( columnIndex ); + else + return sal_Int64( 0 ); + } + + virtual float SAL_CALL + getFloat( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getFloat( columnIndex ); + else + return float( 0 ); + } + + virtual double SAL_CALL + getDouble( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getDouble( columnIndex ); + else + return double( 0 ); + } + + virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getBytes( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBytes( columnIndex ); + else + return com::sun::star::uno::Sequence< sal_Int8 >(); + } + + virtual com::sun::star::util::Date SAL_CALL + getDate( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getDate( columnIndex ); + else + return com::sun::star::util::Date(); + } + + virtual com::sun::star::util::Time SAL_CALL + getTime( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getTime( columnIndex ); + else + return com::sun::star::util::Time(); + } + + virtual com::sun::star::util::DateTime SAL_CALL + getTimestamp( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getTimestamp( columnIndex ); + else + return com::sun::star::util::DateTime(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getBinaryStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBinaryStream( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getCharacterStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getCharacterStream( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >(); + } + + virtual com::sun::star::uno::Any SAL_CALL + getObject( + sal_Int32 columnIndex, + const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getObject( columnIndex,typeMap ); + else + return com::sun::star::uno::Any(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRef > SAL_CALL + getRef( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getRef( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XRef >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob > SAL_CALL + getBlob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBlob( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XClob > SAL_CALL + getClob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getClob( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XClob >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XArray > SAL_CALL + getArray( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getArray( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XArray >(); + } + + + // XResultSet + + virtual sal_Bool SAL_CALL + next( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isBeforeFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isAfterLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + beforeFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + afterLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + first( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + last( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + getRow( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + absolute( + sal_Int32 row ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + relative( + sal_Int32 rows ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + previous( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + refreshRow( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowUpdated( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowInserted( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowDeleted( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + getStatement( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + // XCloseable + + virtual void SAL_CALL + close( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + // XContentAccess + + virtual rtl::OUString SAL_CALL + queryContentIdentifierString( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL + queryContentIdentifier( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL + queryContent( + void ) + throw( com::sun::star::uno::RuntimeException ); + + // XResultSetMetaDataSupplier + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData > SAL_CALL + getMetaData( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + // XPropertySet + virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setPropertyValue( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Any& aValue ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::PropertyVetoException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Any SAL_CALL + getPropertyValue( + const rtl::OUString& PropertyName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + protected: + + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + sal_Int32 m_nRow; + sal_Bool m_nWasNull; + sal_Int32 m_nOpenMode; + sal_Bool m_bRowCountFinal; + + typedef std::vector< com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > > IdentSet; + typedef std::vector< com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > > ItemSet; + typedef std::vector< rtl::OUString > PathSet; + + IdentSet m_aIdents; + ItemSet m_aItems; + PathSet m_aPath; + + com::sun::star::uno::Sequence< com::sun::star::beans::Property > m_sProperty; + com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo > m_sSortingInfo; + + osl::Mutex m_aMutex; + cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; + + cppu::OInterfaceContainerHelper* m_pRowCountListeners; + cppu::OInterfaceContainerHelper* m_pIsFinalListeners; + }; + + +} // end namespace fileaccess + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultsetfactory.hxx b/xmlhelp/source/cxxhelp/provider/resultsetfactory.hxx new file mode 100644 index 000000000000..502fe162e54c --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetfactory.hxx @@ -0,0 +1,27 @@ +#ifndef _RESULTSETFACTORY_HXX +#define _RESULTSETFACTORY_HXX + + +#include "resultsetbase.hxx" + + +namespace chelp { + + class ResultSetBase; + + class ResultSetFactory + { + public: + + virtual ~ResultSetFactory() { }; + + virtual ResultSetBase* createResultSet() = 0; + }; + + + +} + + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx b/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx new file mode 100644 index 000000000000..055b59048722 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx @@ -0,0 +1,449 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/ucb/Command.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/i18n/XExtendedTransliteration.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/script/XInvocation.hpp> + +#ifndef INCLUDED_STL_ALGORITHM +#include <algorithm> +#define INCLUDED_STL_ALGORITHM +#endif +#ifndef INCLUDED_STL_SET +#include <set> +#define INCLUDED_STL_SET +#endif + +#include <qe/Query.hxx> +#include <qe/DocGenerator.hxx> +#include "resultsetforquery.hxx" +#include "databases.hxx" + +// For testing +// #define LOGGING + +using namespace std; +using namespace chelp; +using namespace xmlsearch::excep; +using namespace xmlsearch::qe; +using namespace com::sun::star; +using namespace com::sun::star::ucb; +using namespace com::sun::star::i18n; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +struct HitItem +{ + rtl::OUString m_aURL; + float m_fScore; + + HitItem( void ) {} + HitItem( const rtl::OUString& aURL, float fScore ) + : m_aURL( aURL ) + , m_fScore( fScore ) + {} + bool operator < ( const HitItem& rHitItem ) const + { + return rHitItem.m_fScore < m_fScore; + } +}; + +ResultSetForQuery::ResultSetForQuery( const uno::Reference< lang::XMultiServiceFactory >& xMSF, + const uno::Reference< XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ) + : ResultSetBase( xMSF,xProvider,nOpenMode,seq,seqSort ), + m_pDatabases( pDatabases ), + m_aURLParameter( aURLParameter ) +{ + Reference< XTransliteration > xTrans( + xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.Transliteration" ) ), + UNO_QUERY ); + Locale aLocale( aURLParameter.get_language(), + rtl::OUString(), + rtl::OUString() ); + if(xTrans.is()) + xTrans->loadModule(TransliterationModules_UPPERCASE_LOWERCASE, + aLocale ); + + // Access Lucene via XInvocation + Reference< script::XInvocation > xInvocation( + xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.help.HelpSearch" ) ), + UNO_QUERY ); + + vector< vector< rtl::OUString > > queryList; + { + sal_Int32 idx; + rtl::OUString query = m_aURLParameter.get_query(); + while( query.getLength() ) + { + idx = query.indexOf( sal_Unicode( ' ' ) ); + if( idx == -1 ) + idx = query.getLength(); + + vector< rtl::OUString > currentQuery; + rtl::OUString tmp(query.copy( 0,idx )); + rtl:: OUString toliterate = tmp; + if(xTrans.is()) { + Sequence<sal_Int32> aSeq; + toliterate = xTrans->transliterate( + tmp,0,tmp.getLength(),aSeq); + } + + currentQuery.push_back( toliterate ); + queryList.push_back( currentQuery ); + + int nCpy = 1 + idx; + if( nCpy >= query.getLength() ) + query = rtl::OUString(); + else + query = query.copy( 1 + idx ); + } + } + + vector< rtl::OUString > aCompleteResultVector; + if( xInvocation.is() ) + { + rtl::OUString scope = m_aURLParameter.get_scope(); + bool bCaptionsOnly = ( scope.compareToAscii( "Heading" ) == 0 ); + sal_Int32 hitCount = m_aURLParameter.get_hitCount(); + +#ifdef LOGGING + FILE* pFile = fopen( "d:\\resultset_out.txt", "w" ); +#endif + + IndexFolderIterator aIndexFolderIt( *pDatabases, m_aURLParameter.get_module(), m_aURLParameter.get_language() ); + rtl::OUString idxDir; + bool bExtension = false; + int iDir = 0; + vector< vector<HitItem>* > aIndexFolderResultVectorVector; + + bool bTemporary; + while( (idxDir = aIndexFolderIt.nextIndexFolder( bExtension, bTemporary )).getLength() > 0 ) + { + vector<HitItem> aIndexFolderResultVector; + + try + { + vector< vector<HitItem>* > aQueryListResultVectorVector; + set< rtl::OUString > aSet,aCurrent,aResultSet; + + int nQueryListSize = queryList.size(); + if( nQueryListSize > 1 ) + hitCount = 2000; + + for( int i = 0; i < nQueryListSize; ++i ) + { + vector<HitItem>* pQueryResultVector; + if( nQueryListSize > 1 ) + { + pQueryResultVector = new vector<HitItem>(); + aQueryListResultVectorVector.push_back( pQueryResultVector ); + } + else + { + pQueryResultVector = &aIndexFolderResultVector; + } + pQueryResultVector->reserve( hitCount ); + + int nParamCount = bCaptionsOnly ? 7 : 6; + Sequence<uno::Any> aParamsSeq( nParamCount ); + + aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) ); + aParamsSeq[1] = uno::makeAny( m_aURLParameter.get_language() ); + + aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-index" ) ); + rtl::OUString aSystemPath; + osl::FileBase::getSystemPathFromFileURL( idxDir, aSystemPath ); + aParamsSeq[3] = uno::makeAny( aSystemPath ); + + aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-query" ) ); + + const std::vector< rtl::OUString >& aListItem = queryList[i]; + ::rtl::OUString aNewQueryStr = aListItem[0]; + aParamsSeq[5] = uno::makeAny( aNewQueryStr ); + + if( bCaptionsOnly ) + aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-caption" ) ); + + Sequence< sal_Int16 > aOutParamIndex; + Sequence< uno::Any > aOutParam; + + uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "search" ), + aParamsSeq, aOutParamIndex, aOutParam ); + + Sequence< float > aScoreSeq; + int nScoreCount = 0; + int nOutParamCount = aOutParam.getLength(); + if( nOutParamCount == 1 ) + { + const uno::Any* pScoreAnySeq = aOutParam.getConstArray(); + if( pScoreAnySeq[0] >>= aScoreSeq ) + nScoreCount = aScoreSeq.getLength(); + } + + Sequence<rtl::OUString> aRetSeq; + if( aRet >>= aRetSeq ) + { + if( nQueryListSize > 1 ) + aSet.clear(); + + const rtl::OUString* pRetSeq = aRetSeq.getConstArray(); + int nCount = aRetSeq.getLength(); + if( nCount > hitCount ) + nCount = hitCount; + for( int j = 0 ; j < nCount ; ++j ) + { + float fScore = 0.0; + if( j < nScoreCount ) + fScore = aScoreSeq[j]; + + rtl::OUString aURL = pRetSeq[j]; + pQueryResultVector->push_back( HitItem( aURL, fScore ) ); + if( nQueryListSize > 1 ) + aSet.insert( aURL ); + +#ifdef LOGGING + if( pFile ) + { + rtl::OString tmp(rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, "Dir %d, Query %d, Item: score=%f, URL=%s\n", iDir, i, fScore, tmp.getStr() ); + } +#endif + } + } + + // intersect + if( nQueryListSize > 1 ) + { + if( i == 0 ) + { + aResultSet = aSet; + } + else + { + aCurrent = aResultSet; + aResultSet.clear(); + set_intersection( aSet.begin(),aSet.end(), + aCurrent.begin(),aCurrent.end(), + inserter(aResultSet,aResultSet.begin())); + } + } + } + + // Combine results in aIndexFolderResultVector + if( nQueryListSize > 1 ) + { + for( int n = 0 ; n < nQueryListSize ; ++n ) + { + vector<HitItem>* pQueryResultVector = aQueryListResultVectorVector[n]; + vector<HitItem>& rQueryResultVector = *pQueryResultVector; + + int nItemCount = rQueryResultVector.size(); + for( int i = 0 ; i < nItemCount ; ++i ) + { + const HitItem& rItem = rQueryResultVector[ i ]; + set< rtl::OUString >::iterator it; + if( (it = aResultSet.find( rItem.m_aURL )) != aResultSet.end() ) + { + HitItem aItemCopy( rItem ); + aItemCopy.m_fScore /= nQueryListSize; // To get average score + if( n == 0 ) + { + // Use first pass to create entry + aIndexFolderResultVector.push_back( aItemCopy ); + +#ifdef LOGGING + if( pFile ) + { + rtl::OString tmp(rtl::OUStringToOString( aItemCopy.m_aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, "Combine: Query %d (first pass), Item %d: score=%f (%f), URL=%s\n", n, i, aItemCopy.m_fScore, rItem.m_fScore, tmp.getStr() ); + } +#endif + } + else + { + // Find entry in vector + int nCount = aIndexFolderResultVector.size(); + for( int j = 0 ; j < nCount ; ++j ) + { + HitItem& rFindItem = aIndexFolderResultVector[ j ]; + if( rFindItem.m_aURL.equals( aItemCopy.m_aURL ) ) + { +#ifdef LOGGING + if( pFile ) + { + rtl::OString tmp(rtl::OUStringToOString( aItemCopy.m_aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, "Combine: Query %d, Item %d: score=%f + %f = %f, URL=%s\n", n, i, + rFindItem.m_fScore, aItemCopy.m_fScore, rFindItem.m_fScore + aItemCopy.m_fScore, tmp.getStr() ); + } +#endif + + rFindItem.m_fScore += aItemCopy.m_fScore; + break; + } + } + } + } + } + + delete pQueryResultVector; + } + + sort( aIndexFolderResultVector.begin(), aIndexFolderResultVector.end() ); + } + + vector<HitItem>* pIndexFolderHitItemVector = new vector<HitItem>( aIndexFolderResultVector ); + aIndexFolderResultVectorVector.push_back( pIndexFolderHitItemVector ); + aIndexFolderResultVector.clear(); + } + catch( const Exception& ) + { + } + + ++iDir; + + if( bTemporary ) + aIndexFolderIt.deleteTempIndexFolder( idxDir ); + + } // Iterator + + + int nVectorCount = aIndexFolderResultVectorVector.size(); + vector<HitItem>::size_type* pCurrentVectorIndex = new vector<HitItem>::size_type[nVectorCount]; + for( int j = 0 ; j < nVectorCount ; ++j ) + pCurrentVectorIndex[j] = 0; + +#ifdef LOGGING + if( pFile ) + { + for( int k = 0 ; k < nVectorCount ; ++k ) + { + vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[k]; + int nItemCount = rIndexFolderVector.size(); + + fprintf( pFile, "Vector %d, %d elements\n", k, nItemCount ); + + for( int i = 0 ; i < nItemCount ; ++i ) + { + const HitItem& rItem = rIndexFolderVector[ i ]; + rtl::OString tmp(rtl::OUStringToOString(rItem.m_aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, " Item_vector%d, %d/%d: score=%f, URL=%s\n", k, i, nItemCount, rItem.m_fScore, tmp.getStr() ); + } + } + } +#endif + + sal_Int32 nTotalHitCount = m_aURLParameter.get_hitCount(); + sal_Int32 nHitCount = 0; + while( nHitCount < nTotalHitCount ) + { + int iVectorWithBestScore = -1; + float fBestScore = 0.0; + for( int k = 0 ; k < nVectorCount ; ++k ) + { + vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[k]; + if( pCurrentVectorIndex[k] < rIndexFolderVector.size() ) + { + const HitItem& rItem = rIndexFolderVector[ pCurrentVectorIndex[k] ]; + + if( fBestScore < rItem.m_fScore ) + { + fBestScore = rItem.m_fScore; + iVectorWithBestScore = k; + } + } + } + + if( iVectorWithBestScore == -1 ) // No item left at all + break; + + vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[iVectorWithBestScore]; + const HitItem& rItem = rIndexFolderVector[ pCurrentVectorIndex[iVectorWithBestScore] ]; + + pCurrentVectorIndex[iVectorWithBestScore]++; + + aCompleteResultVector.push_back( rItem.m_aURL ); + ++nHitCount; + } + + delete[] pCurrentVectorIndex; + for( int n = 0 ; n < nVectorCount ; ++n ) + { + vector<HitItem>* pIndexFolderVector = aIndexFolderResultVectorVector[n]; + delete pIndexFolderVector; + } + +#ifdef LOGGING + fclose( pFile ); +#endif + } + + sal_Int32 replIdx = rtl::OUString::createFromAscii( "#HLP#" ).getLength(); + rtl::OUString replWith = rtl::OUString::createFromAscii( "vnd.sun.star.help://" ); + + int nResultCount = aCompleteResultVector.size(); + for( int r = 0 ; r < nResultCount ; ++r ) + { + rtl::OUString aURL = aCompleteResultVector[r]; + rtl::OUString aResultStr = replWith + aURL.copy(replIdx); + m_aPath.push_back( aResultStr ); + } + + m_aItems.resize( m_aPath.size() ); + m_aIdents.resize( m_aPath.size() ); + + Command aCommand; + aCommand.Name = rtl::OUString::createFromAscii( "getPropertyValues" ); + aCommand.Argument <<= m_sProperty; + + for( m_nRow = 0; sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aPath.size(); ++m_nRow ) + { + m_aPath[m_nRow] = + m_aPath[m_nRow] + + rtl::OUString::createFromAscii( "?Language=" ) + + m_aURLParameter.get_language() + + rtl::OUString::createFromAscii( "&System=" ) + + m_aURLParameter.get_system(); + + uno::Reference< XContent > content = queryContent(); + if( content.is() ) + { + uno::Reference< XCommandProcessor > cmd( content,uno::UNO_QUERY ); + cmd->execute( aCommand,0,uno::Reference< XCommandEnvironment >( 0 ) ) >>= m_aItems[m_nRow]; //TODO: check return value of operator >>= + } + } + m_nRow = 0xffffffff; +} diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforquery.hxx b/xmlhelp/source/cxxhelp/provider/resultsetforquery.hxx new file mode 100644 index 000000000000..fcdcdedd60f1 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforquery.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _RESULTSETFORQUERY_HXX +#define _RESULTSETFORQUERY_HXX + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> + +#include "resultsetbase.hxx" +#include "urlparameter.hxx" + +namespace chelp { + + class Databases; + + class ResultSetForQuery + : public ResultSetBase + { + public: + + ResultSetForQuery( const com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory>& xMSF, + const com::sun::star::uno::Reference<com::sun::star::ucb::XContentProvider>& xProvider, + sal_Int32 nOpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ); + + + private: + + Databases* m_pDatabases; + URLParameter m_aURLParameter; + }; + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforroot.cxx b/xmlhelp/source/cxxhelp/provider/resultsetforroot.cxx new file mode 100644 index 000000000000..607ce53b4cc3 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforroot.cxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/ucb/Command.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> + +#include "resultsetforroot.hxx" +#include "databases.hxx" + +using namespace chelp; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + + +ResultSetForRoot::ResultSetForRoot( const uno::Reference< lang::XMultiServiceFactory >& xMSF, + const uno::Reference< XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ) + : ResultSetBase( xMSF,xProvider,nOpenMode,seq,seqSort ), + m_aURLParameter( aURLParameter ), + m_pDatabases( pDatabases ) +{ + m_aPath = m_pDatabases->getModuleList( m_aURLParameter.get_language() ); + m_aItems.resize( m_aPath.size() ); + m_aIdents.resize( m_aPath.size() ); + + Command aCommand; + aCommand.Name = rtl::OUString::createFromAscii( "getPropertyValues" ); + aCommand.Argument <<= m_sProperty; + + for( sal_uInt32 i = 0; i < m_aPath.size(); ++i ) + { + m_aPath[i] = + rtl::OUString::createFromAscii( "vnd.sun.star.help://" ) + + m_aPath[i] + + rtl::OUString::createFromAscii( "?Language=" ) + + m_aURLParameter.get_language() + + rtl::OUString::createFromAscii( "&System=" ) + + m_aURLParameter.get_system(); + + m_nRow = sal_Int32( i ); + + uno::Reference< XContent > content = queryContent(); + if( content.is() ) + { + uno::Reference< XCommandProcessor > cmd( content,uno::UNO_QUERY ); + cmd->execute( aCommand,0,uno::Reference< XCommandEnvironment >( 0 ) ) >>= m_aItems[i]; //TODO: check return value of operator >>= + } + m_nRow = 0xffffffff; + } +} diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforroot.hxx b/xmlhelp/source/cxxhelp/provider/resultsetforroot.hxx new file mode 100644 index 000000000000..79fe8294d777 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforroot.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _RESULTSETFORROOT_HXX +#define _RESULTSETFORROOT_HXX + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> + +#include "resultsetbase.hxx" +#include "urlparameter.hxx" + +namespace chelp { + + class Databases; + + class ResultSetForRoot + : public ResultSetBase + { + public: + + ResultSetForRoot( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ); + + + private: + + URLParameter m_aURLParameter; + Databases* m_pDatabases; + }; + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/services.cxx b/xmlhelp/source/cxxhelp/provider/services.cxx new file mode 100644 index 000000000000..e6d73a4ba2eb --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/services.cxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include "provider.hxx" + +using namespace com::sun::star; + +//========================================================================= +extern "C" void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//========================================================================= +extern "C" void * SAL_CALL component_getFactory( + const sal_Char * pImplName, + void * pServiceManager, + void * /*pRegistryKey*/ ) +{ + void * pRet = 0; + + uno::Reference< lang::XMultiServiceFactory > xSMgr( + reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) ); + uno::Reference< lang::XSingleServiceFactory > xFactory; + + ////////////////////////////////////////////////////////////////////// + // Create factory, if implementation name matches. + ////////////////////////////////////////////////////////////////////// + + if ( ::chelp::ContentProvider::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory = ::chelp::ContentProvider::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx new file mode 100644 index 000000000000..67735c4e0a6a --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx @@ -0,0 +1,1243 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +#define WORKAROUND_98119 + +#ifdef WORKAROUND_98119 +#include "bufferedinputstream.hxx" +#endif + +#include <string.h> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <osl/thread.h> +#include <rtl/memory.h> +#include <osl/file.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/processfactory.hxx> +#include <rtl/uri.hxx> +#include <rtl/ustrbuf.hxx> +#include <libxslt/xslt.h> +#include <libxslt/transform.h> +#include <libxslt/xsltutils.h> +#include "db.hxx" +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifierFactory.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include "urlparameter.hxx" +#include "databases.hxx" + +namespace chelp { + + inline bool ascii_isDigit( sal_Unicode ch ) + { + return ((ch >= 0x0030) && (ch <= 0x0039)); + } + + inline bool ascii_isLetter( sal_Unicode ch ) + { + return ( ( (ch >= 0x0041) && (ch <= 0x005A) ) || + ( (ch >= 0x0061) && (ch <= 0x007A) ) ); + } + + inline bool isLetterOrDigit( sal_Unicode ch ) + { + return ascii_isLetter( ch ) || ascii_isDigit( ch ); + } + +} + +using namespace cppu; +using namespace com::sun::star::io; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace berkeleydbproxy; +using namespace chelp; + + +URLParameter::URLParameter( const rtl::OUString& aURL, + Databases* pDatabases ) + throw( com::sun::star::ucb::IllegalIdentifierException ) + : m_pDatabases( pDatabases ), + m_aURL( aURL ) +{ + init( false ); + parse(); +} + + +bool URLParameter::isErrorDocument() +{ + bool bErrorDoc = false; + + if( isFile() ) + { + Reference< XHierarchicalNameAccess > xNA = + m_pDatabases->findJarFileForPath( get_jar(), get_language(), get_path() ); + bErrorDoc = !xNA.is(); + } + + return bErrorDoc; +} + + +rtl::OString URLParameter::getByName( const char* par ) +{ + rtl::OUString val; + + if( strcmp( par,"Program" ) == 0 ) + val = get_program(); + else if( strcmp( par,"Database" ) == 0 ) + val = get_module(); + else if( strcmp( par,"DatabasePar" ) == 0 ) + val = get_dbpar(); + else if( strcmp( par,"Id" ) == 0 ) + val = get_id(); + else if( strcmp( par,"Path" ) == 0 ) + val = get_path(); + else if( strcmp( par,"Language" ) == 0 ) + val = get_language(); + else if( strcmp( par,"System" ) == 0 ) + val = get_system(); + else if( strcmp( par,"HelpPrefix" ) == 0 ) + val = get_prefix(); + + return rtl::OString( val.getStr(),val.getLength(),RTL_TEXTENCODING_UTF8 ); +} + + +rtl::OUString URLParameter::get_id() +{ + if( m_aId.compareToAscii("start") == 0 ) + { // module is set + StaticModuleInformation* inf = + m_pDatabases->getStaticInformationForModule( get_module(), + get_language() ); + if( inf ) + m_aId = inf->get_id(); + + m_bStart = true; + } + + return m_aId; +} + +rtl::OUString URLParameter::get_tag() +{ + if( isFile() ) + return get_the_tag(); + else + return m_aTag; +} + + +rtl::OUString URLParameter::get_title() +{ + if( isFile() ) + return get_the_title(); + else if( m_aModule.compareToAscii("") != 0 ) + { + StaticModuleInformation* inf = + m_pDatabases->getStaticInformationForModule( get_module(), + get_language() ); + if( inf ) + m_aTitle = inf->get_title(); + } + else // This must be the root + m_aTitle = rtl::OUString::createFromAscii("root"); + + return m_aTitle; +} + + +rtl::OUString URLParameter::get_language() +{ + if( m_aLanguage.getLength() == 0 ) + return m_aDefaultLanguage; + + return m_aLanguage; +} + + +rtl::OUString URLParameter::get_program() +{ + if( ! m_aProgram.getLength() ) + { + StaticModuleInformation* inf = + m_pDatabases->getStaticInformationForModule( get_module(), + get_language() ); + if( inf ) + m_aProgram = inf->get_program(); + } + return m_aProgram; +} + + +void URLParameter::init( bool bDefaultLanguageIsInitialized ) +{ + (void)bDefaultLanguageIsInitialized; + + m_bBerkeleyRead = false; + m_bStart = false; + m_bUseDB = true; + m_nHitCount = 100; // The default maximum hitcount +} + + +rtl::OUString URLParameter::get_the_tag() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + + m_bBerkeleyRead = true; + + return m_aTag; + } + else + return rtl::OUString(); +} + + + +rtl::OUString URLParameter::get_the_path() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + m_bBerkeleyRead = true; + + return m_aPath; + } + else + return get_id(); +} + + + +rtl::OUString URLParameter::get_the_title() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + m_bBerkeleyRead = true; + + return m_aTitle; + } + else + return rtl::OUString(); +} + + +rtl::OUString URLParameter::get_the_jar() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + m_bBerkeleyRead = true; + + return m_aJar; + } + else + return get_module() + rtl::OUString::createFromAscii(".jar"); +} + + + + +void URLParameter::readBerkeley() +{ + static rtl::OUString aQuestionMark( rtl::OUString::createFromAscii( "?" ) ); + + if( get_id().compareToAscii("") == 0 ) + return; + + rtl::OUString aModule = get_module(); + rtl::OUString aLanguage = get_language(); + + DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false ); + bool bSuccess = false; + + int nSize = 0; + const sal_Char* pData = NULL; + + Dbt data; + DBData aDBData; + rtl::OUString aExtensionPath; + rtl::OUString aExtensionRegistryPath; + while( true ) + { + Db* db = aDbIt.nextDb( &aExtensionPath, &aExtensionRegistryPath ); + if( !db ) + break; + + rtl::OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 ); + + DBHelp* pDBHelp = db->getDBHelp(); + if( pDBHelp != NULL ) + { + bSuccess = pDBHelp->getValueForKey( keyStr, aDBData ); + if( bSuccess ) + { + nSize = aDBData.getSize(); + pData = aDBData.getData(); + break; + } + } + else + { + Dbt key( static_cast< void* >( const_cast< sal_Char* >( keyStr.getStr() ) ), + keyStr.getLength() ); + int err = db->get( 0,&key,&data,0 ); + if( err == 0 ) + { + bSuccess = true; + nSize = data.get_size(); + pData = static_cast<sal_Char*>( data.get_data() ); + break; + } + } + } + + if( bSuccess ) + { + DbtToStringConverter converter( pData, nSize ); + m_aTitle = converter.getTitle(); + m_pDatabases->replaceName( m_aTitle ); + m_aPath = converter.getFile(); + m_aJar = converter.getDatabase(); + if( aExtensionPath.getLength() > 0 ) + { + rtl::OUStringBuffer aExtendedJarStrBuf; + aExtendedJarStrBuf.append( aQuestionMark ); + aExtendedJarStrBuf.append( aExtensionPath ); + aExtendedJarStrBuf.append( aQuestionMark ); + aExtendedJarStrBuf.append( m_aJar ); + m_aJar = aExtendedJarStrBuf.makeStringAndClear(); + m_aExtensionRegistryPath = aExtensionRegistryPath; + } + m_aTag = converter.getHash(); + } +} + + + +// Class encapsulating the transformation of the XInputStream to XHTML + + +class InputStreamTransformer + : public OWeakObject, + public XInputStream, + public XSeekable +{ +public: + + InputStreamTransformer( URLParameter* urlParam, + Databases* pDatatabases, + bool isRoot = false ); + + ~InputStreamTransformer(); + + virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); + virtual void SAL_CALL acquire( void ) throw(); + virtual void SAL_CALL release( void ) throw(); + + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException); + + virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException); + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ); + + virtual sal_Int32 SAL_CALL available( void ) throw( NotConnectedException, + IOException, + RuntimeException ); + + virtual void SAL_CALL closeInput( void ) throw( NotConnectedException, + IOException, + RuntimeException ); + + virtual void SAL_CALL seek( sal_Int64 location ) throw( IllegalArgumentException, + IOException, + RuntimeException ); + + virtual sal_Int64 SAL_CALL getPosition( void ) throw( IOException,RuntimeException ); + + virtual sal_Int64 SAL_CALL getLength( void ) throw( IOException,RuntimeException ); + + void addToBuffer( const char* buffer,int len ); + + sal_Int8* getData() const { return (sal_Int8*) buffer; } + + sal_Int32 getLen() const { return sal_Int32( len ); } + +private: + + osl::Mutex m_aMutex; + + int len,pos; + char *buffer; +}; + + + +void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr, + const Command& aCommand, + sal_Int32 CommandId, + const Reference< XCommandEnvironment >& Environment, + const Reference< XOutputStream >& xDataSink ) +{ + (void)rxSMgr; + (void)aCommand; + (void)CommandId; + (void)Environment; + + if( ! xDataSink.is() ) + return; + + if( isPicture() ) + { + Reference< XInputStream > xStream; + Reference< XHierarchicalNameAccess > xNA = + m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ), + get_language() ); + + rtl::OUString path = get_path(); + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } + if( xStream.is() ) + { + sal_Int32 ret; + Sequence< sal_Int8 > aSeq( 4096 ); + while( true ) + { + try + { + ret = xStream->readBytes( aSeq,4096 ); + xDataSink->writeBytes( aSeq ); + if( ret < 4096 ) + break; + } + catch( const Exception& ) + { + break; + } + } + } + } + else + { + // a standard document or else an active help text, plug in the new input stream + InputStreamTransformer* p = new InputStreamTransformer( this,m_pDatabases,isRoot() ); + try + { + xDataSink->writeBytes( Sequence< sal_Int8 >( p->getData(),p->getLen() ) ); + } + catch( const Exception& ) + { + } + delete p; + } + xDataSink->closeOutput(); +} + + + +void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr, + const Command& aCommand, + sal_Int32 CommandId, + const Reference< XCommandEnvironment >& Environment, + const Reference< XActiveDataSink >& xDataSink ) +{ + (void)rxSMgr; + (void)aCommand; + (void)CommandId; + (void)Environment; + + if( isPicture() ) + { + Reference< XInputStream > xStream; + Reference< XHierarchicalNameAccess > xNA = + m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ), + get_language() ); + + rtl::OUString path = get_path(); + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } +#ifdef WORKAROUND_98119 + xDataSink->setInputStream( turnToSeekable(xStream) ); +#else + xDataSink->setInputStream( xStream ); +#endif + } + else + // a standard document or else an active help text, plug in the new input stream + xDataSink->setInputStream( new InputStreamTransformer( this,m_pDatabases,isRoot() ) ); +} + + +// #include <stdio.h> + +void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException ) +{ + // fprintf(stdout,"url send to xmlhelp: %s\n",(rtl::OUStringToOString(m_aURL,RTL_TEXTENCODING_UTF8).getStr())); + m_aExpr = m_aURL; + + sal_Int32 lstIdx = m_aExpr.lastIndexOf( sal_Unicode( '#' ) ); + if( lstIdx != -1 ) + m_aExpr = m_aExpr.copy( 0,lstIdx ); + + if( ! scheme() || + ! name( module() ) || + ! query() || + ! m_aLanguage.getLength() || + ! m_aSystem.getLength() ) + throw com::sun::star::ucb::IllegalIdentifierException(); +} + + +bool URLParameter::scheme() +{ + // Correct extension help links as sometimes the + // module is missing resulting in a misformed URL + if( m_aExpr.compareToAscii( "vnd.sun.star.help:///", 21 ) == 0 ) + { + sal_Int32 nLen = m_aExpr.getLength(); + rtl::OUString aLastStr = m_aExpr.copy( nLen - 6 ); + if( aLastStr.compareToAscii( "DbPAR=" ) == 0 ) + { + rtl::OUString aNewExpr = m_aExpr.copy( 0, 20 ); + rtl::OUString aSharedStr = rtl::OUString::createFromAscii( "shared" ); + aNewExpr += aSharedStr; + aNewExpr += m_aExpr.copy( 20 ); + aNewExpr += aSharedStr; + m_aExpr = aNewExpr; + } + } + + for( sal_Int32 nPrefixLen = 20 ; nPrefixLen >= 18 ; --nPrefixLen ) + { + if( m_aExpr.compareToAscii( "vnd.sun.star.help://", nPrefixLen ) == 0 ) + { + m_aExpr = m_aExpr.copy( nPrefixLen ); + return true; + } + } + return false; +} + + +bool URLParameter::module() +{ + sal_Int32 idx = 0,length = m_aExpr.getLength(); + + while( idx < length && isLetterOrDigit( (m_aExpr.getStr())[idx] ) ) + ++idx; + + if( idx != 0 ) + { + m_aModule = m_aExpr.copy( 0,idx ); + m_aExpr = m_aExpr.copy( idx ); + return true; + } + else + return false; +} + + + +bool URLParameter::name( bool modulePresent ) +{ + // if modulepresent, a name may be present, but must not + + sal_Int32 length = m_aExpr.getLength(); + + if( length != 0 && (m_aExpr.getStr())[0] == sal_Unicode( '/' ) ) + { + sal_Int32 idx = 1; + while( idx < length && (m_aExpr.getStr())[idx] != '?' ) +// ( isLetterOrDigit( (m_aExpr.getStr())[idx] ) +// || (m_aExpr.getStr())[idx] == '/' +// || (m_aExpr.getStr())[idx] == '.' )) + ++idx; + + if( idx != 1 && ! modulePresent ) + return false; + else + { + m_aId = m_aExpr.copy( 1,idx-1 ); + m_aExpr = m_aExpr.copy( idx ); + } + } + +// fprintf(stdout,"id %s\n",(rtl::OUStringToOString(m_aId,RTL_TEXTENCODING_UTF8).getStr())); + return true; +} + + +bool URLParameter::query() +{ + rtl::OUString query_; + + if( ! m_aExpr.getLength() ) + return true; + else if( (m_aExpr.getStr())[0] == sal_Unicode( '?' ) ) + query_ = m_aExpr.copy( 1 ).trim(); + else + return false; + + + bool ret = true; + sal_Int32 delimIdx,equalIdx; + rtl::OUString parameter,value; + + while( query_.getLength() != 0 ) + { + delimIdx = query_.indexOf( sal_Unicode( '&' ) ); + equalIdx = query_.indexOf( sal_Unicode( '=' ) ); + parameter = query_.copy( 0,equalIdx ).trim(); + if( delimIdx == -1 ) + { + value = query_.copy( equalIdx + 1 ).trim(); + query_ = rtl::OUString(); + } + else + { + value = query_.copy( equalIdx+1,delimIdx - equalIdx - 1 ).trim(); + query_ = query_.copy( delimIdx+1 ).trim(); + } + + if( parameter.compareToAscii( "Language" ) == 0 ) + m_aLanguage = value; + else if( parameter.compareToAscii( "Device" ) == 0 ) + m_aDevice = value; + else if( parameter.compareToAscii( "Program" ) == 0 ) + m_aProgram = value; + else if( parameter.compareToAscii( "Eid" ) == 0 ) + m_aEid = value; + else if( parameter.compareToAscii( "UseDB" ) == 0 ) + m_bUseDB = ! ( value.compareToAscii("no") == 0 ); + else if( parameter.compareToAscii( "DbPAR" ) == 0 ) + m_aDbPar = value; + else if( parameter.compareToAscii( "Query" ) == 0 ) + { + if( ! m_aQuery.getLength() ) + m_aQuery = value; + else + m_aQuery += ( rtl::OUString::createFromAscii( " " ) + value ); + } + else if( parameter.compareToAscii( "Scope" ) == 0 ) + m_aScope = value; + else if( parameter.compareToAscii( "System" ) == 0 ) + m_aSystem = value; + else if( parameter.compareToAscii( "HelpPrefix" ) == 0 ) + m_aPrefix = rtl::Uri::decode( + value, + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8 ); + else if( parameter.compareToAscii( "HitCount" ) == 0 ) + m_nHitCount = value.toInt32(); + else if( parameter.compareToAscii( "Active" ) == 0 ) + m_aActive = value; + else + ret = false; + } + + return ret; +} + +struct UserData { + + UserData( InputStreamTransformer* pTransformer, + URLParameter* pInitial, + Databases* pDatabases ) + : m_pTransformer( pTransformer ), + m_pDatabases( pDatabases ), + m_pInitial( pInitial ) + { + } + + InputStreamTransformer* m_pTransformer; + Databases* m_pDatabases; + URLParameter* m_pInitial; +}; + +UserData *ugblData = 0; + +extern "C" { + +static int +fileMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "file:/", 6)) + return 1; + return 0; +} + +static int +zipMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18)) + return 1; + return 0; +} + +static int +helpMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.help:/", 19)) + return 1; + return 0; +} + +static void * +fileOpen(const char *URI) { + osl::File *pRet = new osl::File(rtl::OUString(URI, strlen(URI), RTL_TEXTENCODING_UTF8)); + pRet->open(OpenFlag_Read); + return pRet; +} + +static void * +zipOpen(const char * /*URI*/) { + rtl::OUString language,jar,path; + + if( ugblData->m_pInitial->get_eid().getLength() ) + return (void*)(new Reference< XHierarchicalNameAccess >); + else + { + jar = ugblData->m_pInitial->get_jar(); + language = ugblData->m_pInitial->get_language(); + path = ugblData->m_pInitial->get_path(); + } + + Reference< XHierarchicalNameAccess > xNA = + ugblData->m_pDatabases->findJarFileForPath( jar, language, path ); + + Reference< XInputStream > xInputStream; + + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xInputStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } + + if( xInputStream.is() ) + { + return new Reference<XInputStream>(xInputStream); + } + return 0; +} + +static void * +helpOpen(const char * URI) { + rtl::OUString language,jar,path; + + URLParameter urlpar( rtl::OUString::createFromAscii( URI ), + ugblData->m_pDatabases ); + + jar = urlpar.get_jar(); + language = urlpar.get_language(); + path = urlpar.get_path(); + + Reference< XHierarchicalNameAccess > xNA = + ugblData->m_pDatabases->findJarFileForPath( jar, language, path ); + + Reference< XInputStream > xInputStream; + + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xInputStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } + + if( xInputStream.is() ) + return new Reference<XInputStream>(xInputStream); + return 0; +} + +static int +helpRead(void * context, char * buffer, int len) { + Reference< XInputStream > *pRef = (Reference< XInputStream >*)context; + + Sequence< sal_Int8 > aSeq; + len = (*pRef)->readBytes( aSeq,len); + memcpy(buffer, aSeq.getConstArray(), len); + + return len; +} + +static int +zipRead(void * context, char * buffer, int len) { + if( ugblData->m_pInitial->get_eid().getLength() ) + { + ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len); + return len; + } + else + return helpRead(context, buffer, len); +} + +static int +fileRead(void * context, char * buffer, int len) { + int nRead = 0; + osl::File *pFile = (osl::File*)context; + if (pFile) + { + sal_uInt64 uRead = 0; + if (osl::FileBase::E_None == pFile->read(buffer, len, uRead)) + nRead = static_cast<int>(uRead); + } + return nRead; +} + +static int +uriClose(void * context) { + Reference< XInputStream > *pRef = (Reference< XInputStream >*)context; + delete pRef; + return 0; +} + +static int +fileClose(void * context) { + osl::File *pFile = (osl::File*)context; + if (pFile) + { + pFile->close(); + delete pFile; + } + return 0; +} + +} // extern "C" + +/* +// For debugging only +extern "C" void StructuredXMLErrorFunction(void *userData, xmlErrorPtr error) +{ + (void)userData; + (void)error; + + // Reset error handler + xmlSetStructuredErrorFunc( NULL, NULL ); +} +*/ + +InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, + Databases* pDatabases, + bool isRoot ) + : len( 0 ), + pos( 0 ), + buffer( new char[1] ) // Initializing with one element to avoid gcc compiler warning +{ + if( isRoot ) + { + delete[] buffer; + pDatabases->cascadingStylesheet( urlParam->get_language(), + &buffer, + &len ); + } + else if( urlParam->isActive() ) + { + delete[] buffer; + pDatabases->setActiveText( urlParam->get_module(), + urlParam->get_language(), + urlParam->get_id(), + &buffer, + &len ); + } + else + { + UserData userData( this,urlParam,pDatabases ); + + // Uses the implementation detail, that rtl::OString::getStr returns a zero terminated character-array + + const char* parameter[47]; + rtl::OString parString[46]; + int last = 0; + + parString[last++] = "Program"; + rtl::OString aPureProgramm( urlParam->getByName( "Program" ) ); + parString[last++] = rtl::OString('\'') + aPureProgramm + rtl::OString('\''); + parString[last++] = "Database"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "DatabasePar" ) + rtl::OString('\''); + parString[last++] = "Id"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "Id" ) + rtl::OString('\''); + parString[last++] = "Path"; + rtl::OString aPath( urlParam->getByName( "Path" ) ); + parString[last++] = rtl::OString('\'') + aPath + rtl::OString('\''); + + rtl::OString aPureLanguage = urlParam->getByName( "Language" ); + parString[last++] = "Language"; + parString[last++] = rtl::OString('\'') + aPureLanguage + rtl::OString('\''); + parString[last++] = "System"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "System" ) + rtl::OString('\''); + parString[last++] = "productname"; + parString[last++] = rtl::OString('\'') + rtl::OString( + pDatabases->getProductName().getStr(), + pDatabases->getProductName().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + parString[last++] = "productversion"; + parString[last++] = rtl::OString('\'') + + rtl::OString( pDatabases->getProductVersion().getStr(), + pDatabases->getProductVersion().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + + parString[last++] = "imgrepos"; + parString[last++] = rtl::OString('\'') + pDatabases->getImagesZipFileURL() + rtl::OString('\''); + parString[last++] = "hp"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "HelpPrefix" ) + rtl::OString('\''); + + if( parString[last-1].getLength() ) + { + parString[last++] = "sm"; + parString[last++] = "'vnd.sun.star.help%3A%2F%2F'"; + parString[last++] = "qm"; + parString[last++] = "'%3F'"; + parString[last++] = "es"; + parString[last++] = "'%3D'"; + parString[last++] = "am"; + parString[last++] = "'%26'"; + parString[last++] = "cl"; + parString[last++] = "'%3A'"; + parString[last++] = "sl"; + parString[last++] = "'%2F'"; + parString[last++] = "hm"; + parString[last++] = "'%23'"; + parString[last++] = "cs"; + parString[last++] = "'css'"; + + parString[last++] = "vendorname"; + parString[last++] = rtl::OString("''"); + parString[last++] = "vendorversion"; + parString[last++] = rtl::OString("''"); + parString[last++] = "vendorshort"; + parString[last++] = rtl::OString("''"); + } + + // Do we need to add extension path? + ::rtl::OUString aExtensionPath; + rtl::OUString aJar = urlParam->get_jar(); + + bool bAddExtensionPath = false; + rtl::OUString aExtensionRegistryPath; + sal_Int32 nQuestionMark1 = aJar.indexOf( sal_Unicode('?') ); + sal_Int32 nQuestionMark2 = aJar.lastIndexOf( sal_Unicode('?') ); + if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 ) + { + aExtensionPath = aJar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 ); + aExtensionRegistryPath = urlParam->get_ExtensionRegistryPath(); + bAddExtensionPath = true; + } + else + { + // Path not yet specified, search directly + Reference< XHierarchicalNameAccess > xNA = pDatabases->findJarFileForPath + ( aJar, urlParam->get_language(), urlParam->get_path(), &aExtensionPath, &aExtensionRegistryPath ); + if( xNA.is() && aExtensionPath.getLength() ) + bAddExtensionPath = true; + } + + if( bAddExtensionPath ) + { + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + Reference< XComponentContext > xContext; + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext; + } + if( !xContext.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "InputStreamTransformer::InputStreamTransformer(), no XComponentContext" ), + Reference< XInterface >() ); + } + + rtl::OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionRegistryPath, xContext ); + rtl::OString aExpandedExtensionPath = rtl::OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() ); + + parString[last++] = "ExtensionPath"; + parString[last++] = rtl::OString('\'') + aExpandedExtensionPath + rtl::OString('\''); + + // ExtensionId + rtl::OString aPureExtensionId; + sal_Int32 iSlash = aPath.indexOf( '/' ); + if( iSlash != -1 ) + aPureExtensionId = aPath.copy( 0, iSlash ); + + parString[last++] = "ExtensionId"; + parString[last++] = rtl::OString('\'') + aPureExtensionId + rtl::OString('\''); + } + + for( int i = 0; i < last; ++i ) + parameter[i] = parString[i].getStr(); + parameter[last] = 0; + + rtl::OUString xslURL = pDatabases->getInstallPathAsURL(); + + rtl::OString xslURLascii( + xslURL.getStr(), + xslURL.getLength(), + RTL_TEXTENCODING_UTF8); + xslURLascii += "main_transform.xsl"; + + ugblData = &userData; + + xmlInitParser(); + xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose); + xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose); + xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose); + //xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction ); + + xsltStylesheetPtr cur = + xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr()); + + xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/"); + + xmlDocPtr res = xsltApplyStylesheet(cur, doc, parameter); + if (res) + { + xmlChar *doc_txt_ptr=0; + int doc_txt_len; + xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, res, cur); + addToBuffer((const char*)doc_txt_ptr, doc_txt_len); + xmlFree(doc_txt_ptr); + } + xmlPopInputCallbacks(); //filePatch + xmlPopInputCallbacks(); //helpPatch + xmlPopInputCallbacks(); //zipMatch + xmlFreeDoc(res); + xmlFreeDoc(doc); + xsltFreeStylesheet(cur); + } +} + + +InputStreamTransformer::~InputStreamTransformer() +{ + delete[] buffer; +} + + +Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType ) throw( RuntimeException ) +{ + Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( XInputStream*,this ), + SAL_STATIC_CAST( XSeekable*,this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + + +void SAL_CALL InputStreamTransformer::acquire( void ) throw() +{ + OWeakObject::acquire(); +} + + + +void SAL_CALL InputStreamTransformer::release( void ) throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + osl::MutexGuard aGuard( m_aMutex ); + + int curr,available_ = len-pos; + if( nBytesToRead <= available_ ) + curr = nBytesToRead; + else + curr = available_; + + if( 0 <= curr && aData.getLength() < curr ) + aData.realloc( curr ); + + for( int k = 0; k < curr; ++k ) + aData[k] = buffer[pos++]; + + return curr > 0 ? curr : 0; +} + + +sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + return readBytes( aData,nMaxBytesToRead ); +} + + + +void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + while( nBytesToSkip-- ) ++pos; +} + + + +sal_Int32 SAL_CALL InputStreamTransformer::available( void ) throw( NotConnectedException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return len-pos > 0 ? len - pos : 0 ; +} + + + +void SAL_CALL InputStreamTransformer::closeInput( void ) throw( NotConnectedException, + IOException, + RuntimeException ) +{ +} + + + +void SAL_CALL InputStreamTransformer::seek( sal_Int64 location ) throw( IllegalArgumentException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + if( location < 0 ) + throw IllegalArgumentException(); + else + pos = sal::static_int_cast<sal_Int32>( location ); + + if( pos > len ) + pos = len; +} + + + +sal_Int64 SAL_CALL InputStreamTransformer::getPosition( void ) throw( IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return sal_Int64( pos ); +} + + + +sal_Int64 SAL_CALL InputStreamTransformer::getLength( void ) throw( IOException,RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + return len; +} + + +void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + char* tmp = buffer; + buffer = new char[ len+len_ ]; + rtl_copyMemory( (void*)(buffer),(void*)(tmp),sal_uInt32( len ) ); + rtl_copyMemory( (void*)(buffer+len),(void*)(buffer_),sal_uInt32( len_ ) ); + delete[] tmp; + len += len_; +} diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.hxx b/xmlhelp/source/cxxhelp/provider/urlparameter.hxx new file mode 100644 index 000000000000..5f73c930dcdb --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/urlparameter.hxx @@ -0,0 +1,258 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _URLPARAMETER_HXX_ +#define _URLPARAMETER_HXX_ + +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <com/sun/star/ucb/IllegalIdentifierException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/ucb/Command.hpp> + +namespace chelp { + + + class Databases; + + + class DbtToStringConverter + { + public: + + DbtToStringConverter( const sal_Char* ptr,sal_Int32 len ) + : m_len( len ), + m_ptr( ptr ) + { + } + + + rtl::OUString getHash() + { + if( m_ptr ) + { + sal_Int32 sizeOfFile = ( sal_Int32 ) m_ptr[0]; + rtl::OUString Hash( m_ptr+1,sizeOfFile,RTL_TEXTENCODING_UTF8 ); + sal_Int32 idx; + if( ( idx = Hash.indexOf( sal_Unicode( '#' ) ) ) != -1 ) + return Hash.copy( 1+idx ); + } + return rtl::OUString(); + } + + + rtl::OUString getFile() + { + if( ! m_ptr ) + return rtl::OUString(); + + sal_Int32 sizeOfFile = ( sal_Int32 ) m_ptr[0]; + rtl::OUString File( m_ptr+1,sizeOfFile,RTL_TEXTENCODING_UTF8 ); + sal_Int32 idx; + if( ( idx = File.indexOf( sal_Unicode( '#' ) ) ) != -1 ) + return File.copy( 0,idx ); + else + return File; + } + + + rtl::OUString getDatabase() + { + if( ! m_ptr ) + return rtl::OUString(); + + sal_Int32 sizeOfDatabase = ( int ) m_ptr[ 1+ ( sal_Int32 ) m_ptr[0] ]; + return rtl::OUString( m_ptr + 2 + ( sal_Int32 ) m_ptr[0],sizeOfDatabase,RTL_TEXTENCODING_UTF8 ); + } + + + rtl::OUString getTitle() + { + if( ! m_ptr ) // || getHash().getLength() ) + return rtl::OUString(); + + sal_Int32 sizeOfTitle = + ( sal_Int32 ) m_ptr[ 2 + m_ptr[0] + ( sal_Int32 ) m_ptr[ 1+ ( sal_Int32 ) m_ptr[0] ] ]; + return rtl::OUString( m_ptr + 3 + m_ptr[0] + ( sal_Int32 ) m_ptr[ 1+ ( sal_Int32 ) m_ptr[0] ], + sizeOfTitle, + RTL_TEXTENCODING_UTF8 ); + } + + + private: + + sal_Int32 m_len; + + const sal_Char* m_ptr; + + }; + + + + + class URLParameter + { + public: + + URLParameter( const rtl::OUString& aURL, + Databases* pDatabases ) + throw( com::sun::star::ucb::IllegalIdentifierException ); + + bool isPicture() { return m_aModule.compareToAscii("picture") == 0; } + bool isActive() { return m_aActive.getLength() > 0 && m_aActive.compareToAscii( "true" ) == 0; } + bool isQuery() { return m_aId.compareToAscii("") == 0 && m_aQuery.compareToAscii("") != 0; } + bool isEntryForModule() { return m_aId.compareToAscii("start") == 0 || m_bStart; } + bool isFile() { return m_aId.compareToAscii( "" ) != 0; } + bool isModule() { return m_aId.compareToAscii("") == 0 && m_aModule.compareToAscii("") != 0; } + bool isRoot() { return m_aModule.compareToAscii("") == 0; } + bool isErrorDocument(); + + rtl::OUString get_url() { return m_aURL; } + + rtl::OUString get_id(); + + rtl::OUString get_tag(); + + // Not called for an directory + + rtl::OUString get_path() { return get_the_path(); } + + rtl::OUString get_eid() { return m_aEid; } + + rtl::OUString get_title(); + + rtl::OUString get_jar() { return get_the_jar(); } // BerkeleyDb + + rtl::OUString get_ExtensionRegistryPath() { return m_aExtensionRegistryPath; } + + rtl::OUString get_module() { return m_aModule; } + + rtl::OUString get_dbpar() { + if( m_aDbPar.getLength() ) return m_aDbPar; + else return m_aModule; + } + + rtl::OUString get_prefix() { return m_aPrefix; } + + rtl::OUString get_language(); + + rtl::OUString get_device() { return m_aDevice; } + + rtl::OUString get_program(); + + rtl::OUString get_query() { return m_aQuery; } + + rtl::OUString get_scope() { return m_aScope; } + + rtl::OUString get_system() { return m_aSystem; } + + sal_Int32 get_hitCount() { return m_nHitCount; } + + rtl::OString getByName( const char* par ); + + void open( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment, + const com::sun::star::uno::Reference< com::sun::star::io::XActiveDataSink >& xDataSink ); + + void open( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment, + const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xDataSink ); + + private: + + Databases* m_pDatabases; + + bool m_bBerkeleyRead; + bool m_bStart; + bool m_bUseDB; + + rtl::OUString m_aURL; + + rtl::OUString m_aTag; + rtl::OUString m_aId; + rtl::OUString m_aPath; + rtl::OUString m_aModule; + rtl::OUString m_aTitle; + rtl::OUString m_aJar; + rtl::OUString m_aExtensionRegistryPath; + rtl::OUString m_aEid; + rtl::OUString m_aDbPar; + + rtl::OUString m_aDefaultLanguage; + rtl::OUString m_aLanguage; + + rtl::OUString m_aPrefix; + rtl::OUString m_aDevice; + rtl::OUString m_aProgram; + rtl::OUString m_aSystem; + rtl::OUString m_aActive; + + rtl::OUString m_aQuery; + rtl::OUString m_aScope; + + rtl::OUString m_aExpr; + + sal_Int32 m_nHitCount; // The default maximum hitcount + + + // private methods + + void init( bool bDefaultLanguageIsInitialized ); + + rtl::OUString get_the_tag(); + + rtl::OUString get_the_path(); + + rtl::OUString get_the_title(); + + rtl::OUString get_the_jar(); + + void readBerkeley(); + + void parse() throw( com::sun::star::ucb::IllegalIdentifierException ); + + bool scheme(); + + bool module(); + + bool name( bool modulePresent ); + + bool query(); + + }; // end class URLParameter + + +} // end namespace chelp + +#endif diff --git a/xmlhelp/source/cxxhelp/qe/DocGenerator.cxx b/xmlhelp/source/cxxhelp/qe/DocGenerator.cxx new file mode 100644 index 000000000000..14f9bf5f69c3 --- /dev/null +++ b/xmlhelp/source/cxxhelp/qe/DocGenerator.cxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <qe/DocGenerator.hxx> +#include <qe/Query.hxx> + + +using namespace xmlsearch; +using namespace xmlsearch::qe; + + +const sal_Int32 NonnegativeIntegerGenerator::END = -1; + + +RoleFiller RoleFiller::roleFiller_; + + +RoleFiller::RoleFiller() + : m_nRefcount( 0 ), + fixedRole_( 0 ), + filled_( 0 ), + begin_( 0 ), + end_( 0 ), + parentContext_( 0 ), + limit_( 0 ), + next_( 0 ), + fillers_( 0 ) +{ +} + + +RoleFiller::~RoleFiller() +{ + +} diff --git a/xmlhelp/source/cxxhelp/qe/makefile.mk b/xmlhelp/source/cxxhelp/qe/makefile.mk new file mode 100644 index 000000000000..e55bb9eb3eab --- /dev/null +++ b/xmlhelp/source/cxxhelp/qe/makefile.mk @@ -0,0 +1,49 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME= xmlhelp +TARGET= jaqe +AUTOSEG= TRUE + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +SLOFILES=$(SLO)$/DocGenerator.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/xmlhelp/source/cxxhelp/test/abidebug.hxx b/xmlhelp/source/cxxhelp/test/abidebug.hxx new file mode 100644 index 000000000000..4bffdea764f7 --- /dev/null +++ b/xmlhelp/source/cxxhelp/test/abidebug.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <iostream> +#ifndef _RTL_USTRING_ +#include <rtl/ustring> +#endif +ostream& operator<<( ostream& out,const rtl::OUString& bla ); + diff --git a/xmlhelp/source/cxxhelp/test/makefile.mk b/xmlhelp/source/cxxhelp/test/makefile.mk new file mode 100644 index 000000000000..c255f3fea8dc --- /dev/null +++ b/xmlhelp/source/cxxhelp/test/makefile.mk @@ -0,0 +1,69 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=xmlhelp +TARGET=searchdemo +TARGETTYPE = CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings --- + +.INCLUDE : settings.mk + + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +# --- Files --- + +OBJFILES=\ + $(OBJ)$/searchdemo.obj + +APP1TARGET= searchdemo +APP1OBJS=\ + $(OBJ)$/searchdemo.obj + +APP1STDLIBS=\ + $(SALLIB) \ + $(VOSLIB) + +APP1LIBS=\ + $(SLB)/jaqe.lib \ + $(SLB)/jadb.lib \ + $(SLB)/jautil.lib + +APP1DEF= $(MISC)\$(APP1TARGET).def + +# --- Targets --- + +.INCLUDE : target.mk + diff --git a/xmlhelp/source/cxxhelp/test/searchdemo.cxx b/xmlhelp/source/cxxhelp/test/searchdemo.cxx new file mode 100644 index 000000000000..866a199061a5 --- /dev/null +++ b/xmlhelp/source/cxxhelp/test/searchdemo.cxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <rtl/string.hxx> +#include <osl/file.hxx> +#include <db/Block.hxx> +#include <db/BtreeDictParameters.hxx> +#include <db/BtreeDict.hxx> +#include <util/RandomAccessStream.hxx> +#include <db/DBEnv.hxx> +#include <qe/QueryProcessor.hxx> + +#ifdef ABIDEBUG +#include <abidebug.hxx> +#endif + + +using namespace xmlsearch::util; +using namespace xmlsearch::db; +using namespace xmlsearch::qe; + + + +extern RandomAccessStream* theFile(); + + + +void print_rtl_OUString( const rtl::OUString bla ) +{ + rtl::OString bluber = rtl::OString( bla.getStr(),bla.getLength(),RTL_TEXTENCODING_UTF8 ); + char* bluberChr = new char[ 1+bluber.getLength() ]; + const sal_Char* jux = bluber.getStr(); + + for( int i = 0; i < bluber.getLength(); ++i ) + bluberChr[i] = jux[i]; + + bluberChr[ bluber.getLength() ] = 0; + printf( "%s\n",bluberChr ); + delete[] bluberChr; +} + + +extern void bla(); +extern void blu(); + + +int main( int argc,char* argv[] ) +{ + + QueryResults* queryResults = 0; + + try + { + rtl::OUString installDir = rtl::OUString::createFromAscii( "//./e|/index/" ); + QueryProcessor queryProcessor( installDir ); + + std::vector<rtl::OUString> Query(2); + Query[0] = rtl::OUString::createFromAscii( "text*" ); + Query[1] = rtl::OUString::createFromAscii( "abbildung" ); + rtl::OUString Scope = rtl::OUString::createFromAscii( "headingheading" ); + int HitCount = 40; + + QueryStatement queryStatement( HitCount,Query,Scope ); + queryResults = queryProcessor.processQuery( queryStatement ); + + rtl::OUString translations[2]; + translations[0] = rtl::OUString::createFromAscii( "#HLP#" ); + translations[1] = rtl::OUString::createFromAscii( "vnd.sun.star.help://" ); + + PrefixTranslator* translator = PrefixTranslator::makePrefixTranslator( translations,2 ); + + QueryHitIterator* it = queryResults->makeQueryHitIterator(); + sal_Int32 j = 0; + while( j < 10 && it->next() ) + { + printf( "Ergebnis %2d ",j ); + QueryHitData* qhd = it->getHit( translator ); + printf( "Penalty = %10.4f ",qhd->getPenalty() ); + print_rtl_OUString( qhd->getDocument() ); + ++j; + } + + delete it; + } + catch( ... ) + { + printf( "catched exception" ); + throw; + } + return 0; +} diff --git a/xmlhelp/source/cxxhelp/util/Decompressor.cxx b/xmlhelp/source/cxxhelp/util/Decompressor.cxx new file mode 100644 index 000000000000..63e399c737ce --- /dev/null +++ b/xmlhelp/source/cxxhelp/util/Decompressor.cxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <util/Decompressor.hxx> +#include <util/CompressorIterator.hxx> + +using namespace xmlsearch; +using namespace xmlsearch::util; + +const sal_Int32 Decompressor::BitsInByte = 8; +const sal_Int32 Decompressor::NBits = 32; + +inline sal_Int32 getInteger_( const sal_Int8* v ) +{ + return (((((( (v[0]&0xFF) ) << 8 ) + | (v[1]&0xFF) ) << 8 ) + | (v[2]&0xFF) ) << 8 ) + | (v[3]&0xFF); +} + +sal_Int32 StreamDecompressor::getNextByte() +{ + sal_Int8 a[4]; + a[0] = a[1] = a[2] = 0; + if( in_->readBytes( &a[3],1 ) != -1 ) + return getInteger_( a ); + else + return -1; +} diff --git a/xmlhelp/source/cxxhelp/util/makefile.mk b/xmlhelp/source/cxxhelp/util/makefile.mk new file mode 100644 index 000000000000..a375e7d55c09 --- /dev/null +++ b/xmlhelp/source/cxxhelp/util/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME= xmlhelp +TARGET= jautil +AUTOSEG= TRUE + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +SLOFILES=\ + $(SLO)$/Decompressor.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + |