blob: f8e3f0212d7912a287f94781388c40d8ab2aebde [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_filter.hxx"
#include <filter/msfilter/msfiltertracer.hxx>
#include <vcl/svapp.hxx>
#include <tools/urlobj.hxx>
#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/util/logging/LogLevel.hpp>
#include <com/sun/star/util/SearchAlgorithms.hpp>
#include <com/sun/star/util/SearchFlags.hpp>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <svtools/FilterConfigItem.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/ucbstreamhelper.hxx>
// --------------
// - Namespaces -
// --------------
using namespace ::com::sun::star;
MSFilterTracer::MSFilterTracer( const ::rtl::OUString& rConfigPath, uno::Sequence< beans::PropertyValue >* pConfigData ) :
mpCfgItem( new FilterConfigItem( rConfigPath, pConfigData ) ),
mpAttributeList( new SvXMLAttributeList() ),
mpStream( NULL ),
mbEnabled( sal_False ) // will be set to true in StartTracing()
{
if ( mpCfgItem->ReadBool( rtl::OUString::createFromAscii( "On" ), sal_False ) )
{
uno::Reference< lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
if ( xMgr.is() )
{
/* the following methods try to read a property, if it is not available it will put the second
parameter as default into the property sequence of the FilterConfigItem. It means we ensure that
the property is available by trying to read it (the return value of the method is ignored) */
::rtl::OUString aEmptyString;
mpCfgItem->ReadInt32( rtl::OUString::createFromAscii( "LogLevel" ), util::logging::LogLevel::ALL );
mpCfgItem->ReadString( rtl::OUString::createFromAscii( "ClassFilter" ), aEmptyString );
mpCfgItem->ReadString( rtl::OUString::createFromAscii( "MethodFilter" ), aEmptyString );
mpCfgItem->ReadString( rtl::OUString::createFromAscii( "MessageFilter" ), aEmptyString );
util::SearchAlgorithms eSearchAlgorithm = (util::SearchAlgorithms)
mpCfgItem->ReadInt32( rtl::OUString::createFromAscii( "SearchAlgorithm" ), util::SearchAlgorithms_ABSOLUTE );
// creating the name of the log file
rtl::OUString aPath( mpCfgItem->ReadString( rtl::OUString::createFromAscii( "Path" ), aEmptyString ) );
rtl::OUString aName( mpCfgItem->ReadString( rtl::OUString::createFromAscii( "Name" ), aEmptyString ) );
rtl::OUString aDocumentURL( mpCfgItem->ReadString( rtl::OUString::createFromAscii( "DocumentURL" ), aEmptyString ) );
INetURLObject aLogFile( aDocumentURL );
if ( aLogFile.GetMainURL( INetURLObject::NO_DECODE ).getLength() )
{
if ( aPath.getLength() )
{
String aOldName( aLogFile.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::NO_DECODE ) );
aLogFile = INetURLObject( aPath );
aLogFile.insertName( aOldName );
}
if ( aName.getLength() )
aLogFile.setName( aName );
}
else
{
if ( aPath.getLength() )
aLogFile = INetURLObject( aPath );
else
{
String aURLStr;
if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
{
aLogFile = INetURLObject(aURLStr);
aLogFile .removeSegment();
aLogFile .removeFinalSlash();
}
}
if ( !aName.getLength() )
aName = rtl::OUString::createFromAscii( "tracer" );
aLogFile.insertName( aName );
}
aLogFile.setExtension( rtl::OUString::createFromAscii( "log" ) );
// creating the file stream
mpStream = ::utl::UcbStreamHelper::CreateStream( aLogFile.GetMainURL( INetURLObject::NO_DECODE ), STREAM_WRITE | STREAM_TRUNC | STREAM_SHARE_DENYNONE );
if ( mpStream && !mpStream->GetError() )
{
// creating a wrapper for our stream
utl::OOutputStreamWrapper* pHelper = new ::utl::OOutputStreamWrapper( *mpStream );
uno::Reference< io::XOutputStream > xOutputStream( pHelper );
// instanciating the DocumentHandler, then setting the OutputStream
mxHandler = uno::Reference< xml::sax::XDocumentHandler >( xMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), uno::UNO_QUERY );
uno::Reference< io::XActiveDataSource > xDocSrc( mxHandler, uno::UNO_QUERY );
xDocSrc->setOutputStream( xOutputStream );
mxHandler->startDocument();
mxHandler->ignorableWhitespace ( rtl::OUString::createFromAscii( " " ) );
// writing the "DocumentHandler" property, so the FilterTracer component
// will use it for the output
uno::Any aAny;
aAny <<= xDocSrc;
mpCfgItem->WriteAny( rtl::OUString::createFromAscii( "DocumentHandler" ), aAny );
SvXMLAttributeList* pAttrList = new SvXMLAttributeList;
pAttrList->AddAttribute( rtl::OUString::createFromAscii( "DocumentURL" ), aDocumentURL );
uno::Reference < xml::sax::XAttributeList > xAttributeList(pAttrList);
mxHandler->startElement( rtl::OUString::createFromAscii( "Document" ), xAttributeList );
}
uno::Sequence< uno::Any > aArgument( 1 );
uno::Sequence< beans::PropertyValue > aPropValues( mpCfgItem->GetFilterData() );
aArgument[ 0 ] <<= aPropValues;
mxFilterTracer = xMgr->createInstanceWithArguments( rtl::OUString::createFromAscii( "com.sun.star.util.FilterTracer" ), aArgument );
if ( mxFilterTracer.is() )
{
mxTextSearch = uno::Reference< util::XTextSearch >( mxFilterTracer, uno::UNO_QUERY );
mxLogger = uno::Reference< util::logging::XLogger >( mxFilterTracer, uno::UNO_QUERY );
if ( mxTextSearch.is() )
{
maSearchOptions.algorithmType = eSearchAlgorithm;
mxTextSearch->setOptions( maSearchOptions );
}
}
}
}
}
MSFilterTracer::~MSFilterTracer()
{
mxLogger = NULL;
mxFilterTracer = NULL;
if ( mxHandler.is() )
{
mxHandler->ignorableWhitespace ( rtl::OUString::createFromAscii( " " ) );
mxHandler->endElement( rtl::OUString::createFromAscii( "Document" ) );
mxHandler->ignorableWhitespace ( rtl::OUString::createFromAscii( " " ) );
mxHandler->endDocument();
mxHandler = NULL;
}
delete mpAttributeList;
delete mpCfgItem;
delete mpStream;
}
void MSFilterTracer::StartTracing()
{
mbEnabled = mpCfgItem->ReadBool( rtl::OUString::createFromAscii( "On" ), sal_False );
}
void MSFilterTracer::EndTracing()
{
mbEnabled = sal_False;
}
void MSFilterTracer::StartElement( const rtl::OUString& rName, uno::Reference< xml::sax::XAttributeList > xAttribs )
{
if ( mxHandler.is() )
mxHandler->startElement( rName, xAttribs );
}
void MSFilterTracer::EndElement( const rtl::OUString& rName )
{
if ( mxHandler.is() )
mxHandler->endElement( rName );
}
void MSFilterTracer::Trace( const rtl::OUString& rElement, const rtl::OUString& rMessage )
{
if ( mbEnabled && mxLogger.is() )
{
sal_Bool bFilter = sal_False;
if ( rMessage.getLength() && mxTextSearch.is() )
{
maSearchOptions.searchString = rMessage;
mxTextSearch->setOptions( maSearchOptions );
util::SearchResult aSearchResult = mxTextSearch->searchForward( rMessage, 0, rMessage.getLength() );
bFilter = aSearchResult.subRegExpressions != 0;
}
if ( !bFilter )
{
uno::Reference < xml::sax::XAttributeList > xAttrList( new SvXMLAttributeList( *mpAttributeList ) );
if ( mxHandler.is() )
mxHandler->startElement( rElement, xAttrList );
if ( rMessage.getLength() )
{
rtl::OUString aEmpty;
mxLogger->logp( 0, aEmpty, aEmpty, rMessage );
}
if ( mxHandler.is() )
mxHandler->endElement( rElement );
}
}
}
void MSFilterTracer::AddAttribute( const ::rtl::OUString& sName , const ::rtl::OUString& sValue )
{
if ( mbEnabled )
mpAttributeList->AddAttribute( sName, sValue );
}
void MSFilterTracer::ClearAttributes()
{
if ( mbEnabled )
mpAttributeList->Clear();
}
void MSFilterTracer::RemoveAttribute( const ::rtl::OUString& sName )
{
if ( mbEnabled )
mpAttributeList->RemoveAttribute( sName );
}
uno::Any MSFilterTracer::GetProperty( const rtl::OUString& rPropName, const uno::Any* pDefault ) const
{
uno::Any aDefault;
if ( pDefault )
aDefault = *pDefault;
return mpCfgItem->ReadAny( rPropName, aDefault );
}
void MSFilterTracer::SetProperty( const ::rtl::OUString& rPropName, const uno::Any& rProperty )
{
mpCfgItem->WriteAny( rPropName, rProperty );
}