xref: /trunk/main/desktop/source/deployment/dp_log.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_desktop.hxx"
26 
27 #include "dp_misc.h"
28 #include "rtl/strbuf.hxx"
29 #include "osl/time.h"
30 #include "osl/thread.h"
31 #include "cppuhelper/compbase1.hxx"
32 #include "comphelper/anytostring.hxx"
33 #include "comphelper/servicedecl.hxx"
34 #include "comphelper/unwrapargs.hxx"
35 #include "com/sun/star/deployment/DeploymentException.hpp"
36 #include "com/sun/star/ucb/XProgressHandler.hpp"
37 #include "com/sun/star/ucb/XSimpleFileAccess.hpp"
38 #include "com/sun/star/io/XSeekable.hpp"
39 #include <stdio.h>
40 
41 
42 using namespace ::rtl;
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
45 
46 namespace dp_log {
47 
48 typedef ::cppu::WeakComponentImplHelper1<ucb::XProgressHandler> t_log_helper;
49 
50 //==============================================================================
51 class ProgressLogImpl : public ::dp_misc::MutexHolder, public t_log_helper
52 {
53     Reference<io::XOutputStream> m_xLogFile;
54     sal_Int32 m_log_level;
55     void log_write( OString const & text );
56 
57 protected:
58     virtual void SAL_CALL disposing();
59     virtual ~ProgressLogImpl();
60 
61 public:
62     ProgressLogImpl( Sequence<Any> const & args,
63                      Reference<XComponentContext> const & xContext );
64 
65     // XProgressHandler
66     virtual void SAL_CALL push( Any const & Status );
67     virtual void SAL_CALL update( Any const & Status );
68     virtual void SAL_CALL pop();
69 };
70 
71 //______________________________________________________________________________
~ProgressLogImpl()72 ProgressLogImpl::~ProgressLogImpl()
73 {
74 }
75 
76 //______________________________________________________________________________
disposing()77 void ProgressLogImpl::disposing()
78 {
79     try {
80         if (m_xLogFile.is()) {
81             m_xLogFile->closeOutput();
82             m_xLogFile.clear();
83         }
84     }
85     catch (Exception & exc) {
86         (void) exc;
87         OSL_ENSURE( 0, OUStringToOString(
88                         exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
89     }
90 }
91 
92 //______________________________________________________________________________
ProgressLogImpl(Sequence<Any> const & args,Reference<XComponentContext> const & xContext)93 ProgressLogImpl::ProgressLogImpl(
94     Sequence<Any> const & args,
95     Reference<XComponentContext> const & xContext )
96     : t_log_helper( getMutex() ),
97       m_log_level( 0 )
98 {
99     OUString log_file;
100     boost::optional< Reference<task::XInteractionHandler> > interactionHandler;
101     comphelper::unwrapArgs( args, log_file, interactionHandler );
102 
103     Reference<ucb::XSimpleFileAccess> xSimpleFileAccess(
104         xContext->getServiceManager()->createInstanceWithContext(
105             OUSTR("com.sun.star.ucb.SimpleFileAccess"),
106             xContext ), UNO_QUERY_THROW );
107     // optional ia handler:
108     if (interactionHandler)
109         xSimpleFileAccess->setInteractionHandler( *interactionHandler );
110 
111     m_xLogFile.set(
112         xSimpleFileAccess->openFileWrite( log_file ), UNO_QUERY_THROW );
113     Reference<io::XSeekable> xSeekable( m_xLogFile, UNO_QUERY_THROW );
114     xSeekable->seek( xSeekable->getLength() );
115 
116     // write log stamp
117     OStringBuffer buf;
118     buf.append(
119         RTL_CONSTASCII_STRINGPARAM("###### Progress log entry ") );
120     TimeValue m_start_time, tLocal;
121     oslDateTime date_time;
122     if (osl_getSystemTime( &m_start_time ) &&
123         osl_getLocalTimeFromSystemTime( &m_start_time, &tLocal ) &&
124         osl_getDateTimeFromTimeValue( &tLocal, &date_time ))
125     {
126         char ar[ 128 ];
127         snprintf(
128             ar, sizeof (ar),
129             "%04d-%02d-%02d %02d:%02d:%02d ",
130             date_time.Year, date_time.Month, date_time.Day,
131             date_time.Hours, date_time.Minutes, date_time.Seconds );
132         buf.append( ar );
133     }
134     buf.append( RTL_CONSTASCII_STRINGPARAM("######\n") );
135     log_write( buf.makeStringAndClear() );
136 }
137 
138 //______________________________________________________________________________
log_write(OString const & text)139 void ProgressLogImpl::log_write( OString const & text )
140 {
141     try {
142         if (m_xLogFile.is()) {
143             m_xLogFile->writeBytes(
144                 Sequence< sal_Int8 >(
145                     reinterpret_cast< sal_Int8 const * >(text.getStr()),
146                     text.getLength() ) );
147         }
148     }
149     catch (io::IOException & exc) {
150         (void) exc;
151         OSL_ENSURE( 0, OUStringToOString(
152                         exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
153     }
154 }
155 
156 // XProgressHandler
157 //______________________________________________________________________________
push(Any const & Status)158 void ProgressLogImpl::push( Any const & Status )
159 {
160     update( Status );
161     OSL_ASSERT( m_log_level >= 0 );
162     ++m_log_level;
163 }
164 
165 //______________________________________________________________________________
update(Any const & Status)166 void ProgressLogImpl::update( Any const & Status )
167 {
168     if (! Status.hasValue())
169         return;
170 
171     OUStringBuffer buf;
172     OSL_ASSERT( m_log_level >= 0 );
173     for ( sal_Int32 n = 0; n < m_log_level; ++n )
174         buf.append( static_cast<sal_Unicode>(' ') );
175 
176     OUString msg;
177     if (Status >>= msg) {
178         buf.append( msg );
179     }
180     else {
181         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("ERROR: ") );
182         buf.append( ::comphelper::anyToString(Status) );
183     }
184     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\n") );
185     log_write( OUStringToOString(
186                    buf.makeStringAndClear(), osl_getThreadTextEncoding() ) );
187 }
188 
189 //______________________________________________________________________________
pop()190 void ProgressLogImpl::pop()
191 {
192     OSL_ASSERT( m_log_level > 0 );
193     --m_log_level;
194 }
195 
196 namespace sdecl = comphelper::service_decl;
197 sdecl::class_<ProgressLogImpl, sdecl::with_args<true> > servicePLI;
198 extern sdecl::ServiceDecl const serviceDecl(
199     servicePLI,
200     // a private one:
201     "com.sun.star.comp.deployment.ProgressLog",
202     "com.sun.star.comp.deployment.ProgressLog" );
203 
204 } // namespace dp_log
205