Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "dp_misc.h"
22 : #include <rtl/strbuf.hxx>
23 : #include <osl/time.h>
24 : #include <osl/thread.h>
25 : #include <cppuhelper/compbase1.hxx>
26 : #include <comphelper/anytostring.hxx>
27 : #include <comphelper/servicedecl.hxx>
28 : #include <comphelper/unwrapargs.hxx>
29 : #include <com/sun/star/deployment/DeploymentException.hpp>
30 : #include <com/sun/star/ucb/XProgressHandler.hpp>
31 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
32 : #include <com/sun/star/io/XSeekable.hpp>
33 : #include <stdio.h>
34 :
35 :
36 : using namespace ::com::sun::star;
37 : using namespace ::com::sun::star::uno;
38 :
39 : namespace dp_log {
40 :
41 : typedef ::cppu::WeakComponentImplHelper1<ucb::XProgressHandler> t_log_helper;
42 :
43 :
44 : class ProgressLogImpl : public ::dp_misc::MutexHolder, public t_log_helper
45 : {
46 : Reference<io::XOutputStream> m_xLogFile;
47 : sal_Int32 m_log_level;
48 : void log_write( OString const & text );
49 :
50 : protected:
51 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
52 : virtual ~ProgressLogImpl();
53 :
54 : public:
55 : ProgressLogImpl( Sequence<Any> const & args,
56 : Reference<XComponentContext> const & xContext );
57 :
58 : // XProgressHandler
59 : virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
60 : virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
61 : virtual void SAL_CALL pop() throw (RuntimeException, std::exception) SAL_OVERRIDE;
62 : };
63 :
64 :
65 138 : ProgressLogImpl::~ProgressLogImpl()
66 : {
67 138 : }
68 :
69 :
70 138 : void ProgressLogImpl::disposing()
71 : {
72 : try {
73 138 : if (m_xLogFile.is()) {
74 138 : m_xLogFile->closeOutput();
75 138 : m_xLogFile.clear();
76 : }
77 : }
78 0 : catch (const Exception & exc) {
79 : (void) exc;
80 : OSL_FAIL( OUStringToOString(
81 : exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
82 : }
83 138 : }
84 :
85 :
86 139 : ProgressLogImpl::ProgressLogImpl(
87 : Sequence<Any> const & args,
88 : Reference<XComponentContext> const & xContext )
89 139 : : t_log_helper( getMutex() ),
90 279 : m_log_level( 0 )
91 : {
92 139 : OUString log_file;
93 278 : boost::optional< Reference<task::XInteractionHandler> > interactionHandler;
94 139 : comphelper::unwrapArgs( args, log_file, interactionHandler );
95 :
96 278 : Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess( ucb::SimpleFileAccess::create(xContext) );
97 : // optional ia handler:
98 139 : if (interactionHandler)
99 0 : xSimpleFileAccess->setInteractionHandler( *interactionHandler );
100 :
101 : m_xLogFile.set(
102 139 : xSimpleFileAccess->openFileWrite( log_file ), UNO_QUERY_THROW );
103 276 : Reference<io::XSeekable> xSeekable( m_xLogFile, UNO_QUERY_THROW );
104 138 : xSeekable->seek( xSeekable->getLength() );
105 :
106 : // write log stamp
107 276 : OStringBuffer buf;
108 138 : buf.append( "###### Progress log entry " );
109 : TimeValue m_start_time, tLocal;
110 : oslDateTime date_time;
111 414 : if (osl_getSystemTime( &m_start_time ) &&
112 276 : osl_getLocalTimeFromSystemTime( &m_start_time, &tLocal ) &&
113 138 : osl_getDateTimeFromTimeValue( &tLocal, &date_time ))
114 : {
115 : char ar[ 128 ];
116 : snprintf(
117 : ar, sizeof (ar),
118 : "%04d-%02d-%02d %02d:%02d:%02d ",
119 : date_time.Year, date_time.Month, date_time.Day,
120 138 : date_time.Hours, date_time.Minutes, date_time.Seconds );
121 138 : buf.append( ar );
122 : }
123 138 : buf.append( "######\n" );
124 277 : log_write( buf.makeStringAndClear() );
125 138 : }
126 :
127 :
128 147 : void ProgressLogImpl::log_write( OString const & text )
129 : {
130 : try {
131 147 : if (m_xLogFile.is()) {
132 147 : m_xLogFile->writeBytes(
133 : Sequence< sal_Int8 >(
134 147 : reinterpret_cast< sal_Int8 const * >(text.getStr()),
135 294 : text.getLength() ) );
136 : }
137 : }
138 0 : catch (const io::IOException & exc) {
139 : (void) exc;
140 : OSL_FAIL( OUStringToOString(
141 : exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
142 : }
143 147 : }
144 :
145 : // XProgressHandler
146 :
147 1 : void ProgressLogImpl::push( Any const & Status )
148 : throw (RuntimeException, std::exception)
149 : {
150 1 : update( Status );
151 : OSL_ASSERT( m_log_level >= 0 );
152 1 : ++m_log_level;
153 1 : }
154 :
155 :
156 9 : void ProgressLogImpl::update( Any const & Status )
157 : throw (RuntimeException, std::exception)
158 : {
159 9 : if (! Status.hasValue())
160 9 : return;
161 :
162 9 : OUStringBuffer buf;
163 : OSL_ASSERT( m_log_level >= 0 );
164 9 : for ( sal_Int32 n = 0; n < m_log_level; ++n )
165 0 : buf.append( ' ' );
166 :
167 18 : OUString msg;
168 9 : if (Status >>= msg) {
169 2 : buf.append( msg );
170 : }
171 : else {
172 7 : buf.appendAscii( "ERROR: " );
173 7 : buf.append( ::comphelper::anyToString(Status) );
174 : }
175 9 : buf.appendAscii( "\n" );
176 : log_write( OUStringToOString(
177 18 : buf.makeStringAndClear(), osl_getThreadTextEncoding() ) );
178 : }
179 :
180 :
181 1 : void ProgressLogImpl::pop() throw (RuntimeException, std::exception)
182 : {
183 : OSL_ASSERT( m_log_level > 0 );
184 1 : --m_log_level;
185 1 : }
186 :
187 : namespace sdecl = comphelper::service_decl;
188 111 : sdecl::class_<ProgressLogImpl, sdecl::with_args<true> > servicePLI;
189 111 : extern sdecl::ServiceDecl const serviceDecl(
190 : servicePLI,
191 : // a private one:
192 : "com.sun.star.comp.deployment.ProgressLog",
193 : "com.sun.star.comp.deployment.ProgressLog" );
194 :
195 333 : } // namespace dp_log
196 :
197 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|